模板模式
引言
在C++有模板函数,在生活中有“简历模板”,“论文模板”等等,在程序设计中,也会为一个产品的生成制定一系列的算法流程,这就是模板模式的来历。
- 定义
在一个抽象类中定义一个操作中的算法骨架(简历模板),而将一些步骤延迟到子类中去实现(自己简历内容)。模板方法使得子类可以不改变一个算法的结构前提下,重新定义算法的某些特定步骤,模板方法模式把不变行为搬到超类中,从而去除了子类中的重复代码。 - 架构图
- 生活中例子
房屋建筑师在开发新项目时会使用模板方法。一个典型的规划包括一些建筑平面图,每个平面图体现了不同部分。在一个平面图中,地基、结构、上下水和走线对于每个房间都是一样的。只有在建筑的后期才开始有差别而产生了不同的房屋样式。
模板模式程序
- 情景设计
设计一个类实现对数据库操作,实现数据库数据查询、显示工作:
1.连接数据库(Connect)
2.执行查询命令(Select)
3.显示数据(Display)
4.断开数据库连接(Disconnect)
这些步骤是固定的,但是对于每一张具体的数据表所执行的查询却是不一样的。显然这需要一个抽象角色,给出顶级行为的实现。 -
程序架构图
上图中提供了数据库的查询的框架,在查询数据库时经过连接、执行查询、显示、断开数据库四个步骤,但是查询指令的不同,导致执行查询和显示不一样,所以应用模板模式进行实现。 -
改进的架构图
上图中将不一样的函数进行提取,让其在子类实现,在超类在并设置为抽象类。
在上面的例子中,需要注意的是:
1.对于Connect()和Disconnect()方法实现为了virtual,而Select()和Display()方法则为abstract,这是因为如果这个方法有默认的实现,则实现为virtual,否则为abstract。
2.Run()方法作为一个模版方法,它的一个重要特征是:在基类里定义,而且不能够被派生类更改。有时候它是私有方法(private method),但实际上它经常被声明为protected。它通过调用其它的基类方法(覆写过的)来工作,但它经常是作为初始化过程的一部分被调用的,这样就没必要让客户端程序员能够直接调用它了。
3.在一开始我们提到了不管读的是哪张数据表,它们都有共同的操作步骤,即共同点。因此可以说Template Method模式的一个特征就是剥离共同点。 - 模板方法模式中涉及了两个角色:
抽象模板角色(Vegetable扮演这个角色):定义了一个或多个抽象操作,以便让子类实现,这些抽象操作称为基本操作。
具体模板角色(ChineseCabbage和Spinach扮演这个角色):实现父类所定义的一个或多个抽象方法。 -
综述
模板方法模式在抽象类中定义了算法的实现步骤,将这些步骤的实现延迟到具体子类中去实现,从而使所有子类复用了父类的代码,所以模板方法模式是基于继承的一种实现代码复用的技术。实现了代码复用,能够灵活应对子步骤的变化,符合开放-封闭原则。模板模式在应用可以通过钩子方式(算法封装时,通过判断,决定算法流程和步骤,当然这个钩子需要在子类中重写)。模板模式和策略者模式在一定程度上想似,策略者模式是通过对象组合的方式,经变化的部分进行重构,模板模式是通过继承的方式,实现代码的重构。
版权声明:本文为博主原创文章,未经博主允许不得转载。