关于动态子类层次结构处理设计的问题

时间:2010-05-17 19:00:21

标签: generics oop

我总是倾向于遇到以下设计问题,我不知道如何最好地解决。它通常以我的马戏团的动物等级开始:

Animal
  Cat
    BigCat
  Dog          
  Elephant
  ...

现在,每个Animal都需要接受培训,因此每个动物都有一个单独的方法:

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 个答案:

答案 0 :(得分:2)

您所描述的内容似乎可以通过the Visitor pattern或更精确地双重调度来解决。

让你的动物实施一个可训练的界面:

interface Trainable {

    accept(Trainer trainer);

}

实现如下:

public Dog extends Animal implements Trainable {

  //... other dog stuff

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

}

然后以同样的方式保持训练师。所有动物都会得到适当的调度。

答案 1 :(得分:2)

你基本上实现了visitor pattern的一半。您可以让每个动物提供acceptTrainer(Trainer t)方法,然后调用t.train(this);

然后您的主管会致电animal.acceptTrainer(trainer);

另外,我认为泛型信息被编译出来,所以你不能做任何依赖它们的花哨的东西。最好熟悉一些模式。