Вопрос о дизайне динамической обработки иерархии подклассов - PullRequest
0 голосов
/ 17 мая 2010

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

Animal
  Cat
    BigCat
  Dog          
  Elephant
  ...

Теперь, каждое животное должно быть обучено, так что для каждого есть отдельный метод:

public interface Trainer {
    void train( BigCat animal );
    void train( Dog animal );
    void train( Elephant animal );
    // ...
}

Проблема в том, что CircusDirector наплевать. Он просто бросает животных тренеру, даже не глядя.

public class CircusDirector {
    public void work() {
        Trainer trainer = getTrainer();
        Animal animal = getAnimal();

        // ...and he doesn't know a frog from a pony,
        // so he tries to just:
        trainer.train(animal);
    }
}

Теперь тренер может получить дополнительный метод, такой как

void train( Animal animal );

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

Ответы [ 2 ]

2 голосов
/ 17 мая 2010

Вы по существу реализовали половину шаблона посетителя . Вы можете попросить каждого из ваших животных предоставить метод acceptTrainer(Trainer t), который затем вызовет t.train(this);

Ваш директор тогда позвонит animal.acceptTrainer(trainer);

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

2 голосов
/ 17 мая 2010

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

Пусть ваши животные реализуют обучаемый интерфейс:

interface Trainable {

    accept(Trainer trainer);

}

с реализацией типа:

public Dog extends Animal implements Trainable {

  //... other dog stuff

  public accept(Trainer trainer) {
     trainer.train(this);
  }

}

А потом продолжай в том же духе. Все животные будут отправлены соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...