那么,在单父继承模型中,在保持相同接口(interface)的同时,使代码可扩展以适应 future 更改的最佳解决方案是什么(我想强调的是,这些更改不能在最初实现时就知道了,我的问题的主要焦点是探索支持这些变化的最佳机制/模式当它们出现时)?我知道这是一个非常基本的面向对象问题,下面我提供了我如何解决这个问题的示例,但我想知道是否有更好的解决方案来解决这个常见问题。
这是我一直在做的事情(示例代码是用 Java 编写的):
一开始,创建了以下两个类和接口(interface):
public class Foo
{
protected int z;
}
public interface FooHandler
{
void handleFoo(Foo foo);
}
public class DefaultFooHandler implements FooHandler
{
@Override
public void handleFoo(Foo foo)
{
//do something here
}
}
系统仅使用 FooHandler 类型的变量/字段,并且该对象(在本例中为 DefaultFooHandler)是在几个明确定义的位置(也许有一个 FooHandlerFactory)创建的,以便补偿在未来。
然后,在未来的某个时刻需要扩展 Foo 以添加一些功能。因此,创建了两个新类:
public class ImprovedFoo extends Foo
{
protected double k;
}
public class ImprovedFooHandler extends DefaultFooHandler
{
@Override
public void handleFoo(Foo foo)
{
if(foo instanceof ImprovedFoo)
{
handleImprovedFoo((ImprovedFoo)foo);
return;
}
if(foo instanceof Foo)
{
super.handleFoo(foo);
return;
}
}
public void handleImprovedFoo(ImprovedFoo foo)
{
//do something involving ImprovedFoo
}
}
在上面的示例中,让我感到畏缩的是 ImprovedFooHandler.handleFoo
中出现的 if 语句
有没有办法避免使用 if 语句
和 instanceof
运算符?
最佳答案
首先,您编写的代码将无法工作。
每次当你看到 instanceof
和 if...else
在一起时要非常小心。这些检查的顺序非常重要。在你的情况下,你永远不会执行handleImpovedFoo
。猜猜为什么:)
有这些 instanceof
语句是绝对正常的。有时,这是为子类型提供不同行为的唯一方法。
但在这里你可以使用另一个技巧:使用简单的Map
。将 foo-hierarchy 的类映射到 fooHandler-hierarchy 的实例。
Map<Class<? extends Foo>, FooHandler> map ...
map.put( Foo.class, new FooHandler() );
map.put( ImprovedFoo.class, new ImprovedFooHandler() );
Foo foo ...; // here comes an unknown foo
map.get( foo.getClass() ).handleFoo( foo );
关于java - 关于继承和可扩展性的一般 OO 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5317330/