【问题标题】:When to give up on polymorphism in order to generalize a solution?何时放弃多态性以推广解决方案?
【发布时间】:2014-11-07 20:49:43
【问题描述】:

我有一个名为 SqlPhrase 的接口:

interface SqlPhrase extends SqlElement {
    void include(SqlPhrase ph);
    SqlRoot obtainRoot();
    List<SqlElement> obtainElements(); 
    boolean hasElements();
    SqlPhrase safeCopyOf();
}

这里的关键是safeCopyOf() 方法,我将稍后讨论。我有这个接口的骨架实现,它由实现这个接口的所有具体类共享。骨架实现恰好封装了具体类使用的所有状态。

@Mutable
static abstract class AbstractSqlPhrase implements SqlPhrase {

    private final List<SqlElement>  m_elem;
    private final SqlRoot           m_root;

    AbstractSqlPhrase()
        { m_elem = new ArrayList<>();  m_root = null; } 
    AbstractSqlPhrase(SqlRoot r) 
        { m_elem = new ArrayList<>();  m_root = r; }
    :
    :
}

问题是safeCopyOf() 方法,我想继续并包括预期这个非线程安全类可能需要在并发环境中使用。我已经决定不将类编写为本质上是线程安全的(这会很困难),因为无论如何我希望线程限制成为这些类实例的常用用法。

问题来了:

因为所有的状态都被abstractclass封装了,所以我想在骨架实现中实现safeCopyOf()方法。但是我不能,因为我需要一个具体子类的实例,在这个级别上,我不知道。

多态是解决方案,但我不想在所有具体子类中实现相同的代码,特别是因为我需要执行操作的所有状态都包含在骨架实现中。

另一种解决方案是使用instanceof 运算符并让实例为每个具体子类自行测试。我相信这会奏效,但我不想走这条路,因为它会带来维护负担。

我在这里错过了一个优雅的解决方案吗?

【问题讨论】:

  • 当鹦鹉拒绝改变时,你放弃了多态性。

标签: java polymorphism abstract-class


【解决方案1】:

实现可克隆。方法如下:https://stackoverflow.com/a/4329993/2446277

【讨论】:

  • 克隆具有最终集合字段的对象将导致严重的心痛。您最终会得到两个或更多对象共享一个集合!
猜你喜欢
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
相关资源
最近更新 更多