您是不是在具有闭包/委托/函数指针的编程语言中使用模板方法模式?

Posted

技术标签:

【中文标题】您是不是在具有闭包/委托/函数指针的编程语言中使用模板方法模式?【英文标题】:Do you use Template Method Pattern in programming languages with closures/delegates/function pointers?您是否在具有闭包/委托/函数指针的编程语言中使用模板方法模式? 【发布时间】:2010-09-23 10:25:54 【问题描述】:

在过去的 8 年里,我一直在 C# 和 Java 之间来回奔波。

让我印象深刻的一件事是我已经完全停止使用 C# 中的“模板方法”设计模式。实际上,在 C# 中,我已经开始将这种模式视为一种反模式。

http://en.wikipedia.org/wiki/Template_method_pattern

回到 Java,我发现这种模式是活生生的。我仍然认为它看起来很古老,但意识到在 java 中没有其他方法可以做到这一点。 Java 看起来也很古老;)

既然这无论如何都会出现,为什么它是一个反模式?

很多时候,它会因为“错误的原因”耗尽您的继承层次结构。 基类倾向于散布各种不相关的代码。 它迫使您锁定设计,通常是在开发过程的早期阶段。 (在很多情况下过早锁定) 在稍后阶段更改此设置变得越来越难。

因此,对于闭包/委托/函数指针,您通常会传递一些函数而不是子类化。

回到问题:

如果您的语言有闭包/委托/函数,您是否使用模板方法,何时使用?

【问题讨论】:

【参考方案1】:

当我使用 Java 时,是的。但是对于具有“闭包/委托/功能”的语言,在我的情况下是 Lua,不,我不再使用了,相反,我越来越倾向于 decoration pattern 来满足我的大部分需求。

【讨论】:

【参考方案2】:

是的,我一直使用模板方法,在 D 编程语言中。闭包、委托和函数指针本质上与基类非常松散耦合。当您想要这种松散耦合时,这是一件好事。另一方面,有时您正在自定义的行为本质上与基类非常紧密耦合。这种行为在几乎任何其他情况下都是无用的。在需要这种耦合的情况下,模板方法模式是最简洁、最简单的表达方式。

一个简单的测试是,如果基类和可定制行为之间的通信是单向的,即基类调用可定制行为,那么您应该始终使用策略/闭包/委托/函数指针。如果可自定义的行为需要引用基类以便调用方法等,那么模板方法模式通常是最简单的方法。

【讨论】:

阅读您的答案很有趣。你能举一个例子说明模板方法模式“绝对”是最好的,特别是耦合好的地方吗?只是假设耦合总是很糟糕! @ragu:关键不在于耦合的好坏。关键是它是必要的还是不必要的。如果有必要,那么恕我直言,表达它的最简单方法是模板方法。 我理解您回答手头问题的观点。我的问题很笼统。对我来说,模板模式的耦合是一个不好的副作用。有什么好的耦合例子吗? @ragu:你没有抓住重点。我是说如果策略将与基类紧密耦合并且需要了解很多关于它的知识,那么模板方法模式让这很容​​易表达.耦合从来都不是好事,但有时它是必要的。我只是说,如果您使用策略或委托或其他策略,无论如何策略必须对基类有很多了解并且不能在其他上下文中重用(与基类紧密耦合),那么您真的没有t 解耦了任何东西,但您使代码更冗长且可读性更低。 我喜欢你关于不可避免耦合的模板方法模式的观点。谢谢你的澄清。【参考方案3】:

我会在重新访问此线程时再添加一个答案:

当您自定义基础对象的策略需要相互了解并且仅在所有可能组合的非常有限的子集中才有意义时,模板方法模式比策略模式更好。例如,假设您的基类有一个具体函数doIt() 和钩子beforeDoIt(),旨在允许策略自行初始化,afterDoIt() 旨在允许策略自行清理。您不希望单独设置这些行为,因为它们只有在配对时才有意义。

【讨论】:

以上是关于您是不是在具有闭包/委托/函数指针的编程语言中使用模板方法模式?的主要内容,如果未能解决你的问题,请参考以下文章

C#中的闭包和意想不到的坑

C#中的委托是啥?事件是否一种委托?

Rollo的Python之路Python 闭包:Colsure

➽06闭包

如何在 C# 中使用 委托

iOS Swift:闭包(回调)与委托,何时使用? [关闭]