Я отметил этот вопрос как на Java, так и на Scala, потому что, хотя я в основном занимаюсь разработкой на Java, я хотел бы посмотреть, будет ли решение на Scala отличаться.
У меня проблема с разработкой классов для моего приложения. У меня есть набор общих объектов с разным поведением. Когда я недавно прочитал книгу о шаблонах, я сказал: «Хорошо, я могу использовать шаблон Стратегии здесь», определите поведение как некоторый объект поля и делегируйте ему всю логику. И вот моя проблема началась:)
Допустим, у меня есть утка базового класса, которая может летать, и я делегирую полет в какой-нибудь FlyBehaviour.
interface IFlyable { void fly(); }
interface IFlyBehaviour { void fly(); }
class Duck implements IFlyable {
IFlyBehaviour flyBehaviour;
void fly() {
flyBehaviour.fly();
}
}
Но мои утки немного отличаются, и я понимаю, что хочу, чтобы поведение зависело от этого. Сначала у меня есть SpaceDuck, который должен летать в космосе и использовать поле spaceShip, которое определено только для SpaceDuck. Затем у меня есть HelicopterDuck, который я хочу летать как можно ниже и использую некоторые противовоздушные ракеты, которые определены только для HelicopterDuck. Так что в коде это что-то вроде этого
class SpaceDuck extends Duck {
String spaceship;
}
class SpaceFlyBehaviour implements IFlyBehaviour {
void fly() {
System.out.println("Flying in space on spaceship: " + spaceduck.spaceship);
}
}
class HelicopterDuck extends Duck {
int flares;
}
class HelicopterFlyBehaviour implements IFlyBehaviour {
void fly() {
while(helicopterduck.flares > 0) {
System.out.println("I'm going low and using flares");
helicopterduck.flares--;
}
}
}
Здесь, в моих реализациях поведения, на самом деле у меня нет ссылки на spaceduck или helicopterduck, и этот код не будет компилироваться. Я просто предоставил образец того, как я представлял и хотел бы, чтобы это было. Я мог бы изменить IFlyBehaviour и передать duck в качестве аргумента метода fly (), но затем мне пришлось понизить рейтинг, чтобы получить доступ к определенным полям duck, что, я думаю, не очень хорошая идея.
Похоже, очевидный способ - просто отбросить IFlyBehaviour и переместить метод логики fly () каждой утки. Но я ожидаю много разных способов поведения космических мух и вертолетов, и fly () - не единственный метод. Это будет squack (), run () и т. Д., И каждый из них имеет различный набор поведений. Таким образом, моя иерархия классов станет огромной и непригодной.
В моем реальном приложении у меня будет несколько запускаемых и останавливаемых экземпляров, которые можно запускать и останавливать по-разному. Один экземпляр будет запущен через скрипт SSH, другой - через MBean (или SSH, это зависит от того, как пользователь его настроил), третий - от стороннего производителя и т. Д. Поэтому я надеюсь, что образец Duck достаточно хорошо отразит мою проблему.
Любые мысли, чтобы подтолкнуть меня в правильном направлении, были бы очень полезны. Заранее спасибо!