我有一些动物对象.
我的核心代码希望将所有这些都当作动物对待.每个动物都需要以某种方式进行处理.加工的性质取决于动物的亚型(鸟类,哺乳动物等).
我的代码当前如下所示.
public interface Animal {
public String getTaxonomyClass();
}
public abstract class Bird implements Animal {
@Override
public String getTaxonomyClass() {
return "aves";
}
// Specific to birds
public abstract float getWingspan();
}
public abstract class Mammal implements Animal {
@Override
public String getTaxonomyClass() {
return "mammalia";
}
// Specific to mammals
public abstract int getToothCount();
}
public interface AnimalProcessor {
public String getSupportedTaxonomyClass();
public void process(Animal a);
}
public class MammalProcessor implements AnimalProcessor {
@Override
public String getSupportedTaxonomyClass() {
return "mammalia";
}
@Override
public void process(Animal a) {
System.out.println("Tooth count is " + ((Mammal)a).getToothCount());
}
}
public class BirdProcessor implements AnimalProcessor {
@Override
public String getSupportedTaxonomyClass() {
return "aves";
}
@Override
public void process(Animal a) {
System.out.print("Wingspan is " + ((Bird)a).getWingspan());
}
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ZooKeeper {
Map registry = new HashMap();
public void registerProcessor(AnimalProcessor ap)
{
registry.put(ap.getSupportedTaxonomyClass(), ap);
}
public void processNewAnimals(List newcomers)
{
for(Animal critter : newcomers)
{
String taxonomy = critter.getTaxonomyClass();
if(registry.containsKey(taxonomy))
{
// if I can process the animal, I will
AnimalProcessor ap = registry.get(taxonomy);
ap.process(critter);
}
}
}
}
import java.util.LinkedList;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
ZooKeeper keeper = new ZooKeeper();
keeper.registerProcessor(new MammalProcessor());
keeper.registerProcessor(new BirdProcessor());
List animals = new LinkedList();
animals.add(new Mammal() { // badger
@Override
public int getToothCount() {
return 40;
} }
);
animals.add(new Bird() { // condor
@Override
public float getWingspan() {
return 2.9f;
} }
);
keeper.processNewAnimals(animals);
}
}
通常,这很容易理解,效果很好!我可以随意添加插件新的处理器和动物类型,而无需更改ZooKeeper类或任何接口.您可以想象一个更高级的主类,从数据库中加载动物,然后依次处理它们.
但是,我担心AnimalProcessor子类内部的失败!这让我感到震惊,因为它不应该存在,并且可能违反OO原则.毕竟,此刻我可以将Bird传递给MammalProcessor的process()方法,然后将出现ClassCastException.
谁能建议一种设计模式来解决这个问题?我查看了“访客”模式,但无法弄清楚在这种情况下如何应用它!关键是使核心代码(ZooKeeper)对待所有动物都一样,并使其易于添加对新动物的支持.谢谢!