版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxh2075/article/details/82866981
#ifndef __TEMPLATE_METHOD_H__
#define __TEMPLATE_METHOD_H__
#include <string>
//【说明】
// 模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术。
// 模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。
// 模板方法模式的核心是抽象类和其中的模板方法的设计。子类可以置换掉父类的可变部分,但是子类却不可以改变模板方法所代表的顶级逻辑。
//【定义】
// 模板方法模式:在父类中定义流程处理的框架,在子类中实现具体的处理。
//【角色】
// 1) AbstractClass(抽象模板):在抽象类中定义了一系列基本操作,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。
// 同时,在抽象类中实现了一个模板方法,用于定义一个算法的框架。
// 2) ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤。
//【意义】
// 封装不变部分,扩展可变部分。把认为不变部分的算法封装到父类中实现,而可变部分的则可以通过继承来继续扩展。
// 模板方法可以使逻辑处理通用化,提取公共部分代码,便于维护。
// 按照设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类负责完成具体的事务属性和方法,但是模板方式正好相反,子类执行的结果影响了父类的结果,会增加代码阅读的难度。
//【示例】
//抽象模板,负责定义抽象方法和通用处理流程
class AbstractDisplay
{
public:
AbstractDisplay(){ }
virtual ~AbstractDisplay(){ }
public:
virtual int open() = 0; //基本方法
virtual void play() = 0;
virtual void close() = 0;
void display(); //模板方法
};
//具体对象,负责实现抽象方法
class AudioDisplay : public AbstractDisplay
{
public:
AudioDisplay(const std::string & name);
public:
virtual int open();
virtual void play();
virtual void close();
private:
std::string m_name;
};
//具体对象,负责实现抽象方法
class VideoDisplay : public AbstractDisplay
{
public:
VideoDisplay(const std::string & name);
public:
virtual int open();
virtual void play();
virtual void close();
private:
std::string m_name;
};
//客户端
void TestTemplateMethod();
#endif
#include "TemplateMethod.h"
void AbstractDisplay::display()
{
if (0 == open())
{
play();
close();
}
else
{
printf("open failed \n");
}
}
AudioDisplay::AudioDisplay(const std::string & name)
{
m_name = name;
}
int AudioDisplay::open()
{
printf("open %s.mp3 \n",m_name.c_str());
return 0;
}
void AudioDisplay::play()
{
printf("play %s.mp3 \n", m_name.c_str());
}
void AudioDisplay::close()
{
printf("close %s.mp3 \n", m_name.c_str());
}
int VideoDisplay::open()
{
printf("open %s.avi \n",m_name.c_str());
return -1;
}
void VideoDisplay::play()
{
printf("play %s.avi \n",m_name.c_str());
}
void VideoDisplay::close()
{
printf("close %s.avi \n", m_name.c_str());
}
VideoDisplay::VideoDisplay(const std::string & name)
{
m_name = name;
}
void TestTemplateMethod()
{
AbstractDisplay * display1 = new AudioDisplay(std::string("fly"));
AbstractDisplay * display2 = new VideoDisplay(std::string("hero"));
display1->display();
display2->display();
delete display1;
delete display2;
}