2016-03-01 2 views
2

У меня есть абстрактный класс «TopHandler». Существует два класса, которые расширяют TopHandler: «UserHandler» и «MerchantHandler».Java абстрактный класс - как я могу лучше всего это решить?

У меня есть метод sendMessage(), который я не уверен, где разместить. Один из вариантов, чтобы положить его в TopHandler и создать объект либо UserHandler или MerchantHandler, как это:

public abstract class TopHandler { 

    //Other methods... 

    public void sendMessage() { 

     TopHandler handler; 
     if (message.equalsIgnoreCase("User")) { 
      handler = new UserHandler(); 
      //Call UserHandler implementation of abstract methods 
     } else { 
      handler = new MerchantHandler(); 
      //Call MerchantHandler implementation of abstract methods 
     } 
    } 
} 

Мой другой вариант, чтобы сделать SendMessage() аннотацию и имеют оба класса реализовать, но это действительно создает некоторые дубликат/очень похожий код.

+0

IMO ваша структура достаточно хороша ... возможно, вы хотите проверить [FactoryPattern] (http://www.tutorialspoint.com/design_pattern/factory_pattern.htm) –

+1

зависит от того, нужны ли оба подкласса, и как это необходимо. shoudld это статично? зависит от экземпляра? зависит от типа ??? – Stultuske

+2

Мне кажется странным, что 'TopHandler # sendMessage()' не является статическим, а используется для создания «TopHandler». Но у меня нет полного представления о вашем коде. Во всяком случае, другим решением может быть абстрактный метод TopHandler # createHandler(), который вернет правильный обработчик для каждого подкласса – jhamon

ответ

0

Мое личное мнение заключается в том, что класс не должен знать о своих подклассах.

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

Вы можете найти другое мнение here on programmers stackexchange

Чтобы ответить на ваш вопрос, решение очень простое: overide метод в каждом подклассов. Если есть дублирование, попробуйте реорганизовать свои классы, чтобы переместить большую часть его в классе TopHandler.

Это может быть что-то вроде:

public abstract class TopHandler { 

    //Other methods... 

    public void sendMessage() { 
     TopHandler handler = createHandler(); 
     //Call Handler implementation of abstract methods 
    } 

    public abstract TopHandler createHandler(); 
} 

PS: как не статический метод, то чувствую себя странно, что sendMessage нового создании экземпляра TopHandler. У вас может быть что-то не так. Возможно, вам просто нужно использовать вместо нового обработчика (но трудно сказать, поскольку у нас нет полного кода).

2

Я бы назвал явный метод фабрики, чтобы было ясно, что это то, что он делает.

static TcpHandler create(String mode) { 
    return mode.equalsIgnoreCase("user") ? new UserHandler() : new MerchantHandler(); 
} 

Вы можете вызвать этот метод в своем коде экземпляра.

0

Я предлагаю придерживаться шаблона проектирования стратегии и объявлять sendMessage() в тегах TopHandler. А затем реализуйте метод в классах UserHandler и MerchantHandler.

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

Также удобство чтения лучше, если этот метод реализован в каждом подклассе.

0

Вы должны сделать абстракцию sendMessage() и реализовать их в обоих классах. И попробуйте переместить повторяющиеся коды в отдельный метод внутри класса TopHandler.

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

вы можете прочитать об абстрактном классе here

0

Поскольку sendMessage() определяется в TopHandler и не статично, я полагаю, что, когда вы называете это у вас уже есть конкретная реализация (либо UserHandler или MerchantHandler экземпляр), чтобы вызвать его на ,

Во-первых, не создавайте больше экземпляров в sendMessage() в этом случае.

Держите sendMessage() в TopHandler и неабстрактном, а также создавать абстрактные методы в TopHandler для каждого метода реализации конкретной используемого в sendMessage(). Таким образом, общая реализация будет сохранена в TopHandler, избегая дублирования кода, и только специфики будут реализованы в подклассах.


В качестве альтернативы, если ваше намерение было для sendMessage() быть статическим - в этом случае:

  • делает его аннотация не вариант
  • Первая часть, по существу, завод шаблон (и может быть разделены на его собственный метод для ясности)
  • Фактическая отправка должна выполняться только один раз (не в ветви каждого состояния) и используя (возможно, абстрактные) методы TopHandler
0

Наличие кода if/else, проверяющего тип, говорит о том, что вы делаете это неправильно. Это то, что родилось для наследования и полиморфизма.

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

Рекомендации производителя фабрики/виртуального конструктора.

Смежные вопросы