假设我们有一个Animal类,子类为cat,eagle
现在我有一个方法:
<d:item d:mi="36">
<name d:constr="String" d:mi="15">/Vip/myvip</name>
<irules d:mi="23">
<name d:constr="String" d:mi="22">abcde</name>
</irules>
<irules d:mi="25">
<name d:constr="String" d:mi="24">fgh</name>
</irules>
<irules d:mi="27">
<name d:constr="String" d:mi="26">ijkl</name>
</irules>
此处,cat有两种方法public void process(Animal animal) {
if (animal instanceof Cat) {
if (!animal.meow()) {
throw exception("cat does not meow");
} else {
animal.feedFish();
}
}
if (animal instanceof eagle) {
if (!animal.fly()) {
throw exception("eagle does not fly");
} else {
animal.checkMaxFlightAltitude();
}
}
}
和meow
,它们与鹰的方法feedfish
和fly
完全不同
大多数设计模式都围绕着假设,即子类有一个常见的方法,比如由圈checkmaxflight
继承的Shape draw()
和square draw
是否有某种方法可以对子类进行验证,例如cat and eagle而不进行instanceof检查?
任何好的设计模式(假设子类不在基类中共享方法?)
答案 0 :(得分:7)
您可以在process
中使用抽象Animal
方法并在子类中实现它:
class Animal {
protected abstract void process();
public static void process(Animal a) { a.process(); }
}
class Cat {
void process() {
if (!meow()) throw exception("cat does not meow");
else feedFish();
}
public boolean meow() { ... }
public void feedFish() { ... }
}
答案 1 :(得分:1)
这是多态性派上用场的时候。
abstract class Animal {
abstract public void process(Animal animal);
}
class Cat extends Animal {
@Override
public void process(Animal animal) {
if (!this.meow()) {
throw exception("cat does not meow");
} else {
this.feedFish();
}
}
}
class Eagle extends Animal {
@Override
public void process(Animal animal) {
if (!this.fly()) {
throw exception("eagle does not fly");
} else {
this.checkMaxFlightAltitude();
}
}
}
答案 2 :(得分:1)
您可以使用double dispatch来使用visitor。
示例:
public class Animal {
public abstract void accept(AnimalVisitor v);
public boolean meow() {return false;}
public boolean fly() {return false;}
public void feedFish() {};
public void checkMaxFlightAltitude() {};
}
public class Cat extends Animal {
public void accept(AnimalVisitor v) {
v.visitCat(this);
}
public boolean meow() {return true;}
}
public class Eagle extends Animal {
public void accept(AnimalVisitor v) {
v.visitEagle(this);
}
public boolean fly() {return true;}
}
public interface AnimalVisitor {
void visitEagle(Eagle eagle);
void visitCat(Cat cat);
}
public class AnimalVisitorExample implements AnimalVisitor {
public void visitEagle(Eagle eagle) {
eagle.checkMaxFlightAltitude();
}
public void visitCat(Cat cat) {
cat.feedFish();
}
}
Animal animal = new Cat();
animal.accept(new AnimalVisitorExample());
答案 3 :(得分:1)
(1)是否有某种方法可以对子类进行验证,例如没有instanceof检查的cat和eagle?
是的,有。你可以定义一个&#34;验证&#34;方法(摘要在&#34; Animal&#34;类中)并在特定的子类中实现它。根据验证结果(例如异常/问题列表),您可以使用validate方法抛出某种&#34; InvalidContentException&#34;或者使用&#34; ErrorHandler&#34;提供方法调用。通知实例的坏事。(2)假设子类不在基类中共享一个方法:嗯,那个方法有点反直觉。一方面,你希望能够在&#34; Animal&#34;上做一些事情,但你不想在其上定义该功能?
您可以定义一个具有单独验证方法的Validator类(对于每种类型的&#34; Animal&#34;子类)。这将消除检查的实例,但是你永远无法通过这个Validator类其他&#34;动物&#34; (例如&#34; Dog&#34;),只有&#34; Cat&#34;和#34; Eagle&#34; (或其子类)。您可能还想考虑在传递&#34; Cat&#34;的子类时想要发生什么:以相同方式验证Cat的所有子类,或者是否存在子类特定行为(如颜色,大小......)对于不同的猫类?
- &GT;我想你应该问自己,你是否希望能够验证一般的动物。如果没有深入了解您的问题域(可能有理由不这样做),我建议您进行&#34;验证&#34;关于动物的方法。您也可以选择访问者模式,但这需要Animal有一个&#34; accept(AnimalVisitor visitor)&#34;方法和写入的代码稍多(可能比你想要的更多)