TemplateMethod设计模式
目录
动机(Motivation)
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作 结构,但各个子步骤却有很多改变的需求,或者由于固有的原因 (比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变 化或者晚期实现需求?
模板方法模式的定义如下:
定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。
未使用设计模式的代码:
为了方便和节省时间,命名和具体功能未完成,仅模拟需求和相关代码。
模拟需求:我有一个资源管理器,在初始化的时候分5步初始化,现在我想在其中两步增加一些其他操作我该怎么去做?
TMSCustomManager.h
class UE4DESIGNPATTERN_API TMSCustomManager
{
public:
void Step1()
{
}
void Step2() {}
TMSCustomManager()
{
}
~TMSCustomManager()
{
}
};
TemplateSourceCode.h
#pragma once
#include "CoreMinimal.h"
#include "TMSResourceRegisiterManager.h"
#include "TMSCustomManager.h"
/*
作者:PengCheng
邮箱:mumcome@qq.com
对比参照Source为源文件,optimized文件夹为使用设计模式改写后的代码。
模板模式的源代码,未用任何设计模式。
模拟资源注册器
TMSResourceRegisiterManager
需求:
我有一个资源管理器,我要在资源管理器中加入自己的操作该怎么做。
*/
class UE4DESIGNPATTERN_API TemplateSourceCode
{
public:
//资源管理器
TMSResourceRegisiterManager* m_ResRigisterManager;
//我自己的要插入的操作
TMSCustomManager* m_CustomManager;
TemplateSourceCode()
{
m_ResRigisterManager = new TMSResourceRegisiterManager();
m_CustomManager = new TMSCustomManager();
}
~TemplateSourceCode()
{
delete m_ResRigisterManager;
delete m_CustomManager;
}
void InitalizeSystem()
{
m_CustomManager->Step1();
m_ResRigisterManager->Step1();
m_CustomManager->Step2();
m_ResRigisterManager->Step2();
m_ResRigisterManager->Step3();
m_ResRigisterManager->Step4();
m_ResRigisterManager->Step5();
}
};
TMSResourceRegisiterManager.h
#pragma once
#include "CoreMinimal.h"
/**
*
*/
class UE4DESIGNPATTERN_API TMSResourceRegisiterManager
{
public:
TMSResourceRegisiterManager();
//调用此类应该按照顺序执行
void Step1() {}
void Step2() {}
void Step3() {}
void Step4() {}
void Step5() {}
~TMSResourceRegisiterManager();
};
使用TemplateMethod设计模式的代码:
TemplateOptimizedCode.h
#pragma once
#include "CoreMinimal.h"
#include "TMOResourceRegisiterManager.h"
#include "TMOCustomManager.h"
/*
作者:PengCheng
邮箱:mumcome@qq.com
对比参照Source为源文件,optimized文件夹为使用设计模式改写后的代码。
模板模式的源代码,采用TemplateMethod设计模式进行优化。
模拟资源注册器
TMSResourceRegisiterManager
需求:
我有一个资源管理器,我要在资源管理器中加入自己的操作该怎么做。
*/
class UE4DESIGNPATTERN_API TemplateOptimizedCode
{
public:
TMOResourceRegisiterManager* m_TMOResourceRegisiterManager;
void InitalizeSystem()
{
m_TMOResourceRegisiterManager->Intialize();
}
TemplateOptimizedCode()
{
m_TMOResourceRegisiterManager = new TMOCustomManager();
}
~TemplateOptimizedCode()
{
delete m_TMOResourceRegisiterManager;
}
};
TMOCustomManager.h
#pragma once
#include "CoreMinimal.h"
#include "TMOResourceRegisiterManager.h"
/**
*
*/
class UE4DESIGNPATTERN_API TMOCustomManager:public TMOResourceRegisiterManager
{
public:
virtual void Step1() override {
//执行父类的方法
TMOResourceRegisiterManager::Step1();
//执行自己的操作
//...
}
virtual void Step2() override {
//执行父类的方法
TMOResourceRegisiterManager::Step2();
//执行自己的操作
//...
}
TMOCustomManager();
~TMOCustomManager();
};
TMOResourceRegisiterManager.h
#pragma once
#include "CoreMinimal.h"
/**
*
*/
class UE4DESIGNPATTERN_API TMOResourceRegisiterManager
{
public:
//调用此类应该按照顺序执行
virtual void Step1() {}
virtual void Step2() {}
void Step3() {}
void Step4() {}
void Step5() {}
//初始化,按照顺序执行
void Intialize() {
Step1();
Step2();
Step3();
Step4();
Step5();
}
TMOResourceRegisiterManager();
~TMOResourceRegisiterManager();
};
要点总结
- Template Method模式是一种非常基础性的设计模式,在面向对 象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性) 为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本 实现结构。
- 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用 你”的反向控制结构是Template Method的典型应用。
- 在具体实现方面,被Template Method调用的虚方法可以具有实 现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将 它们设置为protected方法。