在基类中使用对象实例化“挂钩”是否可以?

时间:2008-09-29 09:16:00

标签: java inheritance

我为various reasons创建了自己的Tree实现,并提出了两个类,一个'基础'类,它是一个充满逻辑的通用树节点,另一个类扩展了那个,更专业。

在我的基类中,某些方法涉及实例化新的树节点(例如添加子节点)。这些瞬间是在逻辑内部(比如在嵌套循环中),这使得逻辑难以与瞬时分离。

因此,如果我不在特定类中覆盖这些瞬时,则将创建错误类型的节点。但是,我不希望覆盖这些方法,因为它们还包含不应重复的共享逻辑!

问题可归结为:

public class Foo {
    public String value() { return "foo"; }

    public Foo doStuff() {
        // Logic logic logic..
        return new Foo();
    }
}

class Bar extends Foo {
    public String value() { return "bar"; } 
}

new Bar().doStuff().value(); // returns 'foo', we want 'bar'

突然出现在我头脑中的第一件事就是有一个'create hook',扩展类可以覆盖:

public Foo createFooHook(/* required parameters */) {
  return new Foo();
}

现在。虽然这是一个很好的第一个想法,但是这个代码有些恶臭。关于它,有一些非常...... 错误的

这就像裸体烹饪一样 - 感觉很危险,而且不必要

那么,你会如何处理这种情况?

3 个答案:

答案 0 :(得分:3)

所以,在获得Design Patterns的副本并打开它后,我很确定这是我第一次发现我想要的东西。

它被称为Factory Method,它几​​乎是完美的契合。它仍然有点难看,因为我的超类(上例中的Foo)不是抽象的,这意味着子类不会被强制实现钩子。

虽然可以通过一些重构来解决这个问题,但我最终会得到一些结果:

abstract class AbstractFoo {
    public String value() { return "Foo"; }

    public AbstractFoo doStuff() {
        // Logic logic logic
        return hook();
    }

    protected abstract AbstractFoo hook();
}

class Foo extends AbstractFoo {
    protected AbstractFoo hook() { return new Foo(); }
}

class Bar extends AbstractFoo {
    public String value() { return "Bar"; }

    protected AbstractFoo hook() { return new Bar(); }
}

new Bar().doStuff().value(); // Returns 'Bar'!

答案 1 :(得分:1)

除了Factory模式之外,我还会看一下Composite模式 - 它倾向于在基于树的情况下使用Factory。

Composite Design Pattern

答案 2 :(得分:0)

我认为没有更好的方法。注意不要从构造函数中调用这些钩子。