【问题标题】:Should I use events or the "template method" pattern for an open source library?我应该为开源库使用事件还是“模板方法”模式?
【发布时间】:2013-09-19 16:45:40
【问题描述】:

我正在构建一个开源库,我可以总结如下:

class SuperThing {
    public function doStuff($object) {
        // ...
    }
}

我想为库的用户提供添加自定义行为的可能性。

例如,他可能想在操作中的特定点插入一些日志记录,或者他可能想在某个点修改对象。

我看到了两种方法:

  • template method 模式似乎合适,但它会迫使我添加 很多 受保护的方法(如 beforeDoingThingA()afterDoingThingA()...),它会强制图书馆的用户来扩展我的课程以添加他的行为。

  • 使用事件:SuperThing::doStuff() 引发事件,用户可以随意注册。

对我来说,使用事件似乎更简单、更清晰、更易于维护......

但在我看来,事件主要是关于发送发生某事的消息。不允许有人“钩”入操作并修改某些对象。 也许我错了。

那么事件是否适合这种情况?如果没有,是否有模板方法模式的替代方案?

【问题讨论】:

标签: oop events design-patterns template-method-pattern


【解决方案1】:

订阅事件应该是可选的;如果您对此感到满意,那么他们是有可能的。

每次我实现模板方法模式时,我都会后悔。它假定图书馆的客户(通常是我的更高版本)总是想要:

DoA();
// do some hardcoded or non-virtual stuff
DoB();
// ...
DoC();

不可避免地,我想更改 A、B 和 C 的顺序,更改硬编码的内容,或者我(或其他开发人员)在编写模板时没有想到的其他内容。我正在尝试编写 Open-Closed 代码,但我经常失败。

使用小组件并组合它们是另一种选择;依赖注入是另一个。第三个是更倾向于函数式编程并将委托或函数指针传递给方法,或组合函数。每个选项都有其优点和缺点;我认为没有一个正确的答案。

【讨论】:

    【解决方案2】:

    您始终可以组合多种模式。在这个例子中,为什么不同时提供一个事件系统和模板方法呢?这样用户就可以选择一个或另一个(或两者)来做他们想做的事。

    但是,根据您所做的工作,模板方法可能还不够。我经常发现,如果我正在制作一个“管道”,我会编写一些可互换的小型组件,用户可以将这些组件以各种组合串起来做他们想做的事情,还可以监听管道运行时触发的事件。

    管道非常简单,它只是按照提供的顺序执行组件(所以我猜这是命令模式)并且管道和组件都可以向侦听器触发事件​​。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多