代码之家  ›  专栏  ›  技术社区  ›  SCdF

在基类中使用对象实例化“hooks”可以吗?

  •  2
  • SCdF  · 技术社区  · 17 年前

    我已经为创建了自己的树实现 various reasons 并且提出了两个类,一个“基本”类,它是一个充满逻辑的通用树节点,另一个类扩展了一个更专业的类。

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

    因此,如果我不重写特定类中的这些实例化,将创建错误类型的节点。但是,我没有 希望 重写这些方法,因为它们还包含不应重复的共享逻辑!

    问题可以归结为:

    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'
    

    第一件事,突然出现在我的脑海中会有一个“创建钩子”,扩展类可以覆盖它:

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

    现在。虽然这是一个好的第一个想法,但有一股恶臭从代码中散发出来,有些可怕的东西。有一些非常… 错误的 关于它。

    就像光着身子做饭——感觉很危险,而且 不必要的 .

    所以, 你将如何处理这种情况?

    3 回复  |  直到 17 年前
        1
  •  3
  •   SCdF    17 年前

    所以,在收到我的 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'!
    
        2
  •  1
  •   Tim Mooney    17 年前

    除了工厂模式之外,我还要看一看复合模式——在基于树的情况下,它更适合与工厂一起工作。

    Composite Design Pattern

        3
  •  0
  •   mitchnull    17 年前

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