Должен ли я создать статический метод или абстрактный суперкласс - PullRequest
7 голосов
/ 16 декабря 2011

Я пытаюсь реорганизовать проект, в котором есть одни и те же методы, которые распределены по различным классам.Чтобы уменьшить дублирование кода, я должен переместить общий код в абстрактный суперкласс или поместить его в статический метод в служебном классе?

РЕДАКТИРОВАТЬ Некоторые из методов предназначены для общих вещей, которые, я считаю, можно сделать статическими.В то время как есть другие, которые ссылаются на атрибуты класса, в этом случае я думаю, что имеет смысл сделать его абстрактным суперклассом.

Ответы [ 7 ]

6 голосов
/ 16 декабря 2011

Хорошо, я следую правилу: Не используйте базовый класс для удаления дублирования кода, используйте служебный класс.

Для наследования задайте себе вопрос: Существуют ли отношения Is-A?

Другое правило, которое в большинстве случаев является правильным: Предпочитать композицию наследованию

использование статического служебного класса НЕ является истинной композицией, но его можно назвать производным от него.

Примените эти правила к вашим secenrios и примите решение, принимая во внимание обслуживание и масштабируемость. Однако было бы хорошо, если бы вы могли добавить больше деталей в свой квестон.

2 голосов
/ 16 декабря 2011

Это зависит от того, что делает ваш код. Это полезные методы? Это специфические / специализированные методы класса? Это тяжелое многопоточное приложение?

Имейте в виду, что если вы сделаете их статичными, а ваше приложение будет многопоточным, вам придется защитить их от блокировок. Это, в свою очередь, уменьшает параллелизм. В этом случае, в зависимости от того, сколько потоков вызывает один и тот же кусок кода, вы можете рассмотреть возможность его перемещения (кода) в суперкласс.

1 голос
/ 16 декабря 2011

Как уже упоминали другие, ответ на этот вопрос зависит от контекста проблемы и дублированного кода.

Что нужно учитывать

  • Изменяет ли дублирующийся код экземпляр объекта. В этом случае защищенный метод в общем абстрактном классе
  • Вместо того, чтобы утилитный класс Static рассматривал одноэлементный, статические методы могут быть проблематичными для чистого модульного тестирования, хотя инфраструктуры тестирования становятся лучше в этом.
  • Наследование может быть непросто, если подумать, действительно ли эти объекты из разных классов связаны между собой и требуют некоторого ре-факторинга ОО? или они являются непересекающимися частями доменной логики, которые требуют одинаковых кусков кода.
1 голос
/ 16 декабря 2011

Другим важным моментом может быть тип работы, выполняемый этими функциями.Если это разбросано, вы должны создать класс фасад / помощник / утилит со статическими методами.

0 голосов
/ 16 декабря 2011

На первый взгляд, я бы сказал, что было бы лучше сделать общий код открытым общедоступным статическим методом в открытом классе.Это сделает метод полезным для любого класса, просто используя

    UtilityClassName.methodName();

Это лучше, чем сделать его конкретным методом в абстрактном суперклассе, потому что тогда вам всегда нужно будет расширять этот суперкласс во всехклассы, где вы хотите использовать этот единственный метод.

Но теперь, как вы сказали, поведение метода зависит от некоторых переменных.Теперь, если это зависит от переменных экземпляра разных классов, лучше добавить этот метод в интерфейс, и пусть все ваши классы реализуют этот интерфейс и имеют свою собственную реализацию того же самого.

Но опять же, если эти переменныепостоянные значения, то есть эти постоянные значения в интерфейсе.Реализуйте эти интерфейсы в своем служебном классе.И снова сделайте его статическим методом в этом служебном классе, который будет напрямую использовать эти константы.

Для, например, рассмотрим следующее.общий код возвращаемой области круга.

    public interface TwoDimensional{
        double PI = 3.14;
    }

    public class MyUtility implements TwoDimensional{
        public static double getCircleArea(double radius){
            return PI*radius*radius;
        } 
    }

Здесь вы можете видеть, что метод getCircleArea () зависит от радиуса, который будет различным для разных классов, но все же я могу передать это значение статическому методукласса myUtility.

0 голосов
/ 16 декабря 2011

Если методы используют много полей или методов класса, они не должны быть статическими.Если они являются тем, что подкласс может захотеть изменить, они не должны быть статичными.Если методы должны быть частью интерфейса, они не могут быть статичными.

В противном случае это ваш вызов, и вы, вероятно, передумаете позже.: -)

0 голосов
/ 16 декабря 2011

Если он не использует членов класса, вы можете сделать это статично!

Но вы должны сделать это в абстрактном классе или классе матери

...