关闭

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

标签: 设计模式
108人阅读 评论(0) 收藏 举报
分类:

概述

在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序。但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。
例子1:银行业务办理流程
在银行办理业务时,一般都包含几个基本固定步骤:
取号排队->办理具体业务->对银行工作人员进行评分。
取号取号排队和对银行工作人员进行评分业务逻辑是一样的。但是办理具体业务是个不相同的,具体业务可能取款、存款或者转账。

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

适用性
1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2)各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3)控制子类扩展。模板方法只在特定点调用“ hook”操作 ,这样就只允许在这些点进行扩展。

结构

这里写图片描述

参与者
AbstractClass: 定义抽象的原语操作(primitive operation) ,具体的子类将重定义它们以实现一个算法, 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义

ConcreteClass: 实现原语操作以完成算法中与特定子类相关的步骤。

协作
concreteclass靠abstractclass实现算法中不变的步骤

效果

模板方法模式的优点:
1)模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。
2)模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
3)模板方法模式导致一种反向的控制结构,这种结构有时被称为“好莱坞法则” ,即“别找我们,,我们找你”通过一个父类调用其子类的操作(而不是相反的子类调用父类),通过对子类的扩展增加新的行为,符合“开闭原则”

模板方法模式的缺点:
每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高。

实现

#ifndef _TEMPLATEMETHOD_H_
#define _TEMPLATEMETHOD_H_

//抽象模板,并定义了一个模板方法。
class AbstractClass
{
public:
    ~AbstractClass();
    //具体的模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,它们都推迟到子类中实现
    void TemplateMethod();
    //一些抽象行为,放到子类中去实现
    virtual void PrimitiveOperation1()=0;
    virtual void PrimitiveOperation2()=0;
protected:
    AbstractClass();
private:
};

//实现基类所定义的抽象方法
class ConcreteClassA : public AbstractClass
{
public:
    ConcreteClassA();
    ~ConcreteClassA();
    //实现基类定义的抽象行为
    virtual void PrimitiveOperation1();
    virtual void PrimitiveOperation2();
private:
};

//实现基类所定义的抽象方法
class ConcreteClassB : public AbstractClass
{
public:
    ConcreteClassB();
    ~ConcreteClassB();
    //实现基类定义的抽象行为
    virtual void PrimitiveOperation1();
    virtual void PrimitiveOperation2();
private:
};
#endif
#include "TemplateMethod.h"
#include <iostream>

using namespace std;

AbstractClass::AbstractClass()
{}

AbstractClass::~AbstractClass()
{}

void AbstractClass::TemplateMethod()
{
    this->PrimitiveOperation1();
    this->PrimitiveOperation2();
}

ConcreteClassA::ConcreteClassA()
{}

ConcreteClassA::~ConcreteClassA()
{}

void ConcreteClassA::PrimitiveOperation1()
{
    cout << "ConcreteClassA::PrimitiveOperation1" << endl;
}

void ConcreteClassA::PrimitiveOperation2()
{
    cout << "ConcreteClassA::PrimitiveOperation2" << endl;
}

ConcreteClassB::ConcreteClassB()
{}

ConcreteClassB::~ConcreteClassB()
{}

void ConcreteClassB::PrimitiveOperation1()
{
    cout << "ConcreteClassB::PrimitiveOperation1" << endl;
}

void ConcreteClassB::PrimitiveOperation2()
{
    cout << "ConcreteClassB::PrimitiveOperation2" << endl;
}
#include "TemplateMethod.h"

int main()
{
    //ConcreteClassA与ConcreteClassB可相互替换
    AbstractClass* pAbstract = new ConcreteClassA();
    pAbstract->TemplateMethod();

    pAbstract = new ConcreteClassB();
    pAbstract->TemplateMethod();

    return 0;
}

代码部分参考于:http://www.cnblogs.com/jiese/p/3180477.html

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9557次
    • 积分:608
    • 等级:
    • 排名:千里之外
    • 原创:51篇
    • 转载:15篇
    • 译文:0篇
    • 评论:9条
    文章分类