java - 关于继承和可扩展性的一般 OO 问题

标签 java oop design-patterns inheritance extensibility

那么,在单父继承模型中,在保持相同接口(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 运算符?

最佳答案

首先,您编写的代码将无法工作。 每次当你看到 instanceofif...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/

相关文章:

java - 使用JNI时如何设置 `jps`显示的主类?

php - IoC容器+单元测试

linq-to-sql - 你如何使用 LinqToSQL/ Entity Framework /NHibernate 实现管道和过滤器模式?

java - 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

java - 如何创建自定义二进制协议(protocol)服务器?

javax.persistence.PersistenceException : org. hibernate.PersistentObjectException: 错误

java - 构造函数和构造函数重载

ruby - 当追溯到最原始的方法时,被破坏(修改)的对象总是接收者吗?

java - 哪种面向对象的 GUI 设计能够正确地结合命令模式和观察者模式?

c# - 处理横切问题,例如 Web 应用程序组件的内部统计报告