我应该为开源库使用事件或“模板方法”模式吗?

时间:2013-09-19 16:45:40

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

我正在构建一个开源库,我可以总结一下这样的东西:

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

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

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

我看到了两种方法:

  • template method模式似乎合适,但它会强制我添加很多受保护的方法(例如beforeDoingThingA()afterDoingThingA() ...) ,它将强制库的用户扩展我的类以添加他的行为。

  • 使用事件:SuperThing::doStuff()引发事件,用户可以注册到他想要的任何一个。

使用事件似乎更简单,更清晰,更易于维护......

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

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

2 个答案:

答案 0 :(得分:0)

订阅活动应该是可选的;如果你对此感到满意,他们就有可能。

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

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

我不可避免地要改变A,B和C的顺序,更改硬编码的东西,或者在编写模板时我或(或其他开发人员)想到的其他东西。我正在尝试编写Open-Closed代码,而且我经常会失败。

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

答案 1 :(得分:0)

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

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

管道很简单,只是按照提供的顺序执行组件(所以我猜这是Command模式),管道和组件都可以向侦听器发出事件。