我正在阅读有关设计模式的内容,特别是有关模板方法的内容,这时我的注意力被SO上的this问题吸引了。
在阅读了解释和具体代码后,我仍然想知道为什么这是“模板方法”设计模式的示例。
根据 GoF 的说法,该模式的意图是:
“在操作中定义算法的骨架,将一些步骤推迟到子类。模板方法允许子类重新定义算法的某些步骤,而不改变算法的结构。”
并且有两个参与者:
抽象类:
- 定义具体子类定义的抽象基元操作以实现算法的步骤
- 实现定义算法骨架的模板方法。模板方法调用原始操作以及 AbstractClass 或其他对象中定义的操作。
具体类:
实现原始操作来执行算法的子类特定步骤。
为什么“JdbcOperations”中的代码被认为是“模板方法”设计模式?
我发现它对于消除样板代码非常方便。但为什么这是一个模板方法而不仅仅是一个漂亮的编码技巧。对我来说,它看起来不像模板方法所具有的任何特征。
GoF 中的两种设计模式代表了相似的想法 -
“在操作(通用 API)中定义算法的骨架,并将一些专门的步骤委托给客户端。
模板设计模式:专业化是通过子类化来完成的。 (这不是JdbcTemplate中的做法。
策略:专业化是通过回调(委托)完成的。 (这是JdbcTemplate中的方法。我们使用像ResultSetExtractor这样的回调来提供专门化逻辑)
JdbcTemplate is more a strategy than template.
我同意 -
JdbcTemplate
不是模板方法设计模式的示例。使用的设计模式是callback。
请注意,两种模式的目标和效果非常相似,主要区别在于 template method 使用继承,而 callback 使用组合(某种程度上) - 请参阅 https://en.wikipedia.org/wiki/ Composition_over_inheritance 为什么这可能是首选。
根据
JdbcTemplate
文档
它简化了 JDBC 的使用并有助于避免常见错误。它 执行核心 JDBC 工作流程,让应用程序代码提供 SQL 并提取结果。此类执行 SQL 查询或更新, 启动 ResultSet 迭代并捕获 JDBC 异常 将它们转换为通用的、信息更丰富的异常层次结构 定义在 org.springframework.dao 包中。
JdbcTemplate
为每个方法的内部工作提供抽象。例如insert()
或 update()
在内部使用所选数据库的具体类的实现。
客户端代码不必了解或实现这些方法,因为它们是由数据库供应商实现的。这就是它与 Template
设计模式紧密匹配的原因。
请注意,JdbcTemplate 也不完全是一个策略。在策略模式中,策略是一个实例变量。我想知道为模式的每个变体命名是否有用 - 而且库创建者似乎并不太关心。
我猜 Spring 的创建者更多地关注的是模板背后的想法,而不是技术细节。模板方法模式的名字意味着它的核心思想是我们有一个已经编码的固定动作序列,以及一个我们想要稍后创建和设计的变体部分。
继承的使用可能在某种程度上是一个技术细节。原始版本(为 C++ 设计,没有区分接口和抽象类)使用继承。 JdbcTemplate 而是传递一个接口。在某种程度上,重要且相关的部分是什么: