第24章 行为型模式—模板方法模式

1. 模板方法模式(Template Method Pattern)的定义

(1)定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

(2)模板方法模式的结构和说明

  ①AbstractClass:抽象类。用于定义算法骨架和抽象的原语操作,具体的子类通过重定义这些原语操作来实现一个算法的各个步骤。在这个类里面,还可以提供算法中通用的实现。此外,该类还实现了一个模板方法,它定义了算法的骨架。该模板方法不仅调用原语操作,也调用AbstractClass或其他对象中的操作

  ②ConcreteClass:具体实现类。用来实现算法骨架中的某些步骤,完成与特定子类相关的功能。

【编程实验】在线购物流程

//行为型模式——模板方式模式
//场景:在线购物
/*
网购,天猫或者京东,经历一下四个步骤:
①访问网站   //访问协议和网址不同
②浏览下单   //假设两个网站操作一样
③支付       //天猫:支付宝,东京;货到付款
④收货       //确认操作一样
注意:两个网站第2步和第4步都是一样的,但访问和支付的访问不一样
*/
#include <iostream>
#include <string>

using namespace std;

//抽象模板方法
class OnLineShop
{
protected:
    virtual void accessURL() = 0; //由子类去实现
    virtual void pay() = 0;       //由子类去实现

private:

    void createOrder()
    {
        cout << "创建订单成功" << endl;
    }

    void receiptGoods()
    {
        cout << "收到了物品" << endl;
    }

public:
    //购物
    void shop()
    {
        accessURL();    //第1步:访问网站
        createOrder();  //第2步:浏览下单
        pay();          //第3步:支付
        receiptGoods(); //第4步:收货
    }
};

//天猫
class Tmall :public OnLineShop
{
public:
    void accessURL()
    {
        cout << "https://www.tmall.com/" << endl;
    }

    void pay()
    {
        cout <<"支付宝"<< endl;
    }
};

//京东
class JD :public OnLineShop
{
public:
    void accessURL()
    {
        cout << "http://www.jd.com/" << endl;
    }

    void pay()
    {
        cout <<"货到付款"<< endl;
    }
};

int main()
{
    OnLineShop* tmall = new Tmall();
    tmall->shop();

    cout << endl;

    OnLineShop* jd = new JD();
    jd->shop();

    return 0;
}
/*输出结果:
https://www.tmall.com/
创建订单成功
支付宝
收到了物品

http://www.jd.com/
创建订单成功
货到付款
收到了物品
*/

2. 思考模板方法模式

(1)模板方法模式的本质固定算法骨架

(2)模板方法模式的核心:处理某个流程的代码己经都具备,但是其中某些节点的代码不能确定。因此,将这些节点的代码实现转移给子类完成。即处理步骤父类中己经定义好,具体实现延迟到子类中定义。

(3)模板方法中的变与不变

  ①需要变化的地方都通过纯虚函数,把具体实现延迟到子类中。

  ②不变的部分,进行公共实现。

(4)好莱坞法则:Don’t call me, I’ll call you

  ①正常的控制结构:子类调用父类方法,这很正常因为子类继承了父类,所以是知道父类的。

  ②反向的控制结构父类调用子类方法,因为父类是不可能知道子类的,所以这也是一种反向的控制结构。在C++中是通过虚函数实现的

3. 模板的写法

(1)模板方法:就是定义算法骨架的方法。如上例中的shop()

(2)具体的操作:在模板中直接实现的某些步骤方法,这些步骤的实现通常是固定的,不怎么会变化的,因此可以将其当作公共功能实现在模板中。如果不需子类访问这些函数,可以定义为private。子类需要访问定义为protected

(3)具体的AbstractClass操作:在模板中实现某些公共功能,可以提供给子类使用,一般不是具体的算法步骤的实现,而是一些辅助的公共功能。

(4)原语操作:就是在模板中定义的纯虚函数,通常是模板方法需要调用的操作,是必须的操作,而且在父类中还没办法确定下来如何实现,需要子类来真正实现的方法

(5)钩子操作:在模板中定义,并提供默认实现的操作,这些方法通常被视为可扩展的点,但不是必须的,子类可以有选择地覆盖这些方法,以提供新的实现来扩展功能,这些函数一般被声明为virtual。

4. 模板方法的优缺点

(1)优点:实现代码复用。通过把子类的公共功能抽取出来,放到模板中去实现。

(2)缺点:算法骨架不容易升级。模板方法模式最基本的功能是通过模板的制定把算法骨架完全固定下来。事实上模板和子类是非常耦合的,如果要对模板中的算法骨架进行变更,可能要求所有相关的子类进行相应的变化。所以抽取算法骨架时应尽量确保是不会变化的部分才放到模板中。

5. 模板方法的应用场景

(1)数据库访问的封装

(2)实现一个算法时,整体步骤很固定。但是某些部分易变,这部分可以抽象出来,留给子类去实现。

(3)各个子类中具有公共行为,应该抽取出来,集中在一个公共类中去实现,实现代码复用。

(4)需要控制子类扩展的情况。模板方法模式会在特定的点来调用子类的方法,这样只允许在这些点进行扩展。

6. 相关模式

(1)模板方法和工厂方法

模板方法可以通过工厂方法模式获取需要调用的对象

(2)模板方法模式和策略模式

  ①从表面上看,两个模式都能实现算法的封装,但模板方法封装的是算法的骨架,这个骨架是不变的,变化的是算法中某些步骤的具体实现;而策略模式是把某个步骤的具体实现算法封装起来,所有封装的算法对象是等价的,可以相互替换。

  ②可以在模板方法中使用策略模式,就是把那些变化的算法步骤使用实现策略模式来实现,但是具体选择哪个策略还是要由外部来确定,而整体的算法步骤,也就是算法骨架则由模板方法来定义了

时间: 2024-08-05 03:06:12

第24章 行为型模式—模板方法模式的相关文章

18 行为型模式-----模板方法模式

模式动机(Template Method Pattern):所谓模板,就是具有通用性的一个框架,在不同的具体环境下可以匹配不同的行为.在程序设计中,代码的复用一直是人们追求的目标,更好地利用已有的设计,不仅可以极大地提高开发效率,而且也能保证软件本身的鲁棒性. 一种代码复用的基本原则就是继承机制,但是我们也知道,普通的继承可能会造成派生类比较臃肿,具有“强制性”实现的特性,特别是基类为抽象接口时更是如此.如何让基类承担更多的一般性职责,这就是模板方法模式所解决的问题了. 在模板方法中,将算法的框

设计模式(行为型)之模板方法模式(Template Method Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之命令模式(Command Pattern)>http://blog.csdn.net/yanbober/article/details/45500113 概述 模板方法模式是一种基于继承的代码复用,它是一种类行为型模式:是结构最简单的行为型设计模式,在其结构

行为型模式-模板方法模式

行为型模式又可以分成以下四类:第一类:通过父类与子类的关系进行实现.第二类:两个类之间.第三类:类的状态.第四类:通过中间类 模板方法模式属于第一类,父类与子类的关系 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模板类中可包含要实现的模板方法,还可以包含基本方法,基本方法分三类 (1) 抽象方法:一个抽象方法由抽象类声明.由其具体子类实现.在C#语言里一个抽象方法以abstract关键字标识. (2) 具体方法

&quot;围观&quot;设计模式(18)--行为型之模板方法模式(TemplateMethod Pattern)

模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤.----WIKIPEDIA 个人理解 模板方法模式相对而言比较简单,一般的都是由抽象类定义好模板方法,然后,子类通过继承并实现其父类中定义好的模板中需要执行的具体的方法,调用子类对象的模板方法时,会执行该类中的具体实现的方法.这个模式我个人的感觉有点像是面向过程的操作,执行完一道工序,接着下一道工序. 案例解析 模板方法相对来说比较简单,这里只列举一个例子供大

24 种设计模式之 外观模式+模板方法模式

面向 对象的设计,外观模式和模板方法模式类似,都是封装 ,某个程序 需要很多类,而且很多地方要用. 便创建一个新的类,把拥有所有类的实例,从而使 代码简洁: 这个模式呢,有个最大的特点将细粒度的对象包装成粗粒度的对象,应用程序通过 访问这个外观对象,来完成细粒度对象的调用,外观模式一般是分布式应用和系统架构中的应用服务层的设计中常用的方式,并且一般结合外观模式+DTO 来完成服务层的设计,提供分布式应用服务的高效服务,外观模式我们可以这样理解,我们通过外观的包装,使应用程序只能看到外观对象,而不

Java设计模式之模板方法模式或者说模板设计模式(属于行为型)

抽象类,不变的代码写了,要变化的部分留给子类去实现: package 行为型_模板方法模式; //模板设计模式的意思是把不变定位部分写出来,变化的部分留给子类去实现 public abstract class GetTime { public long getTime() throws Exception{ long start = System.currentTimeMillis();//开始时间 /* //for循环 for(int i=0;i<10000;i++){ System.out.

设计模式-行为型模式-策略模式

策略模式 在实际工作中我用到了策略模式,但为什么要有环境角色呢? 这里我贴上英文对含义的介绍, The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. 然后看看这种设计模式的组成, 一般的,策略模式

JavaScript设计模式与开发实践 模板方法模式

一.模板方法模式的定义和组成 模板方法模式是一种只需使用继承就可以实现的非常简单的模式. 模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序.子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法. 二.第一个例子--Coffee or Tea 我们先来泡一杯咖啡,泡咖啡的步骤通常如下: 把水煮沸 用沸水冲泡咖啡 把咖啡倒进杯子 加糖和牛奶 var Coffee

模板方法模式----你该找对象了(二)

上一篇小编叙述 模仿方法模式 模板方法模式----你该找对象了(一) 目录 1.概述 2.结构与分析 3.拓展 4.模式总结 3.拓展 钩子方法给子类留了"后门"可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制.(体现灵活性)        上篇博客续集,情侣之间约约会,看看电影,喝喝咖啡,调情调情还是不错的.说到喝咖啡,这不来到星巴克咖啡店 ,我们要了一杯咖啡,当漂亮的服务员问你:"先生,您是否要加调料?"你是呆呆地站在那--还