Я отметил этот вопрос как Java, так и Scala, потому что, хотя я в основном развивается на Java, я хотел бы узнать, будет ли решение на Scala другим.Проектирование классов с общим интерфейсом, но по-разному.
У меня возникла проблема с проектированием классов для моего приложения. У меня есть набор общих объектов с различным поведением. Когда я недавно прочитал некоторую книгу о шаблонах, я сказал: «Хорошо, я могу использовать шаблон стратегии здесь», определить поведение как некоторый объект поля и делегировать ему всю логику. И вот моя проблема началась :)
Предположим, у меня есть базовый класс Duck, который может летать, и я делегирую полет в какой-нибудь FlyBehaviour.
interface IFlyable { void fly(); }
interface IFlyBehaviour { void fly(); }
class Duck implements IFlyable {
IFlyBehaviour flyBehaviour;
void fly() {
flyBehaviour.fly();
}
}
Но мои утки немного разные, и я понимаю, что я хочу, чтобы поведение зависело от него. Сначала у меня есть SpaceDuck, который должен летать в космосе и использовать поле spaceShip, которое определяется только для SpaceDuck. Затем у меня есть 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 и передать утку в качестве аргумента методу fly(), но затем мне нужно сжать, чтобы получить доступ к уткам, которые, по-моему, не очень хорошая идея.
Похоже, что очевидный способ - просто отбросить IFlyBehaviour и переместить логику в метод fly() каждой утки. Но я ожидаю, что многие различные виды космических полетов и поведение вертолетов и fly() не являются единственным методом. Это будут squack(), run() и т. Д., И каждый из них имеет разные настройки поведения. Таким образом, моя иерархия классов станет огромной и неподъемной.
В моем реальном приложении у меня будут некоторые запущенные и остановившиеся экземпляры, которые можно запускать и останавливать по-разному. Один экземпляр будет запущен через SSH-скрипт, другой через MBean (или SSH, это зависит от того, как пользователь настроил его), третий с помощью какой-то третьей стороны и т. Д. Поэтому я надеюсь, что образец Duck хорошо отразит мою проблему.
Любые мысли, чтобы подтолкнуть меня в правильном направлении, были бы очень полезными. Заранее спасибо!
это может вас заинтересовать: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ –
Выглядит интересно. Спасибо, что поделился. – Soteric