考虑以下类设计:
public class SuperType { };
public class SubType1 extends SuperType { };
public class SubType2 extends SuperType { };
public class SubType3 extends SuperType { };
public class Tuple {
SuperType t1;
SuperType t2;
public Tuple(SuperType t1, SuperType t2) {
this.t1 = t1;
this.t2 = t2;
}
public void DoSomething1() {
if((t1 instanceof SubType1) && (t2 instanceof SubType3))
switch(t1, t2);
else if((t1 instanceof SubType2) && (t2 instanceof SubType1))
t1.DoSomething();
else if( ... ) {
t1.DoSomething();
t2.DoSomething();
}
else if( ... )
// ...
}
public void DoSomething2() {
// basically the same
}
}
由于操作依赖于两种类型,因此我无法通过将方法移至子类型来避免使用instanceof 运算符。有没有办法改进我的设计,从而避免使用instanceof?
我知道这里有很多类似的问题,但我想避免使用访问者,因为我有大约 20 个 DoSomething() 方法,这将导致 Visit() 的 9*20 实现。
最佳答案
在面向对象语言中执行此操作的正确方法是使用称为“双重调度”的模式(Googlable,但维基百科的页面不太好)。
“append”方法就是一个很好的例子:
class Super
{
abstract void appendTo(Super target);
abstract void append(Sub1 source);
abstract void append(Sub2 source);
}
class Sub1
{
void appendTo(Super target)
{
target->append(this); //calls the Sub1 overload
}
void append(Sub1 source)
{
... this is Sub1, source is Sub1 ...
}
void append(Sub2 source)
{
... this is Sub1, source is Sub2 ...
}
}
class Sub2
{
void appendTo(Super target)
{
target->append(this); //calls the Sub2 overload
}
void append(Sub1 source)
{
... this is Sub2, source is Sub1 ...
}
void append(Sub2 source)
{
... this is Sub2, source is Sub2 ...
}
}
关于Java 在设计上避免了instanceof,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33463495/