Должен ли я создать статический метод или абстрактный суперкласс

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

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


person Community    schedule 16.12.2011    source источник
comment
Невозможно ответить без контекста; Многое зависит от того, насколько тесно связаны существующие классы, как используются классы и методы и т. Д.   -  person Dave Newton    schedule 16.12.2011
comment
Вы должны рассказать нам больше об этих методах - если они разделяют одно и то же поведение и могут действовать независимо от любых классов, а затем наличие коммунальных классов со статическими методами имеет смысл. Если вы думаете об использовании абстрактных классов / базовых классов / интерфейсов, вы должны учитывать, имеет ли имеющие ли эти классовые иерархии, и будут ли эти функции действительно поведения в том, что эти классы или, как упоминалось ранее, эти методы не волнуют о классе они являются частью.   -  person wkl    schedule 16.12.2011
comment
Можете ли вы объяснить, что делает метод и связаны ли все эти классы?   -  person Bhesh Gurung    schedule 16.12.2011
comment
Дайте еще одну информацию, связанную с тем, что на самом деле вы пытаетесь сделать.   -  person Sumit Singh    schedule 16.12.2011
comment
Я спросил почти такой же вопрос: stackoverflow.com/questions/5312193 /базовый-класс-против-служебного-класса. Посмотрите, поможет ли это.   -  person Azodious    schedule 16.12.2011


Ответы (7)


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

Для наследования, задайте вопрос себе: Есть отношения - это отношения?

Еще одно правило, которое в большинстве случаев правильное, звучит так: Предпочитайте композицию наследованию.

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

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

person Azodious    schedule 16.12.2011
comment
Больше деталей уменьшило бы количество догадок, но мне нравятся эмпирические правила, которые вы упомянули. - person James Drinkard; 11.09.2013

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

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

person Adrian    schedule 16.12.2011
comment
Вам нужно блокировать статические методы только в том случае, если они сохраняют состояние - person user949300; 16.12.2011
comment
@ user949300 я согласен. Я делал предположения. - person Adrian; 16.12.2011

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

person Nrj    schedule 16.12.2011

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

Некоторые вещи, которые следует учитывать

  • Изменяет ли дублированный код экземпляр объекта. В этом случае защищенный метод в общем абстрактном классе
  • Вместо статического класса Utility рассмотрите Singleton, статические методы могут быть проблематичными для тестирования чистого блока, хотя структуры тестирования поправляются на этом.
  • Наследование может быть сложным для правильного понимания, подумайте, действительно ли эти объекты из разных классов связаны и требуют некоторого рефакторинга ООП? или это непересекающиеся части доменной логики, которые требуют одинаковых фрагментов кода.
person bluphoenix    schedule 16.12.2011

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

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

person Matthias Bruns    schedule 16.12.2011
comment
Это довольно рано утром здесь: x Не ожидайте слишком много: D - person Matthias Bruns; 16.12.2011

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

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

person user949300    schedule 16.12.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.

person whitehat    schedule 16.12.2011