网站关键词库,前端开发培训机构哪个好,wordpress时间做旧,北京今天最新新闻文章目录 一、模板方法模式概述二、模板方法模式UML图三、优点1代码复用性高2可维护性好3扩展性强 四、缺点五、使用场景六、C 代码示例1七、 C 代码示例2 一、模板方法模式概述
定义#xff1a;定义一个操作中的算法骨架#xff0c;而降一些步骤延迟到子类中。模板方法使得… 文章目录 一、模板方法模式概述二、模板方法模式UML图三、优点1代码复用性高2可维护性好3扩展性强 四、缺点五、使用场景六、C 代码示例1七、 C 代码示例2 一、模板方法模式概述
定义定义一个操作中的算法骨架而降一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 定义模板方法模式是一种行为设计模式。它在一个抽象类中定义了一个算法的骨架模板方法将一些步骤的实现延迟到子类中。模板方法定义了算法的步骤顺序子类可以根据自身的需求重写其中的某些步骤而整体算法的流程结构保持不变。
二、模板方法模式UML图 三、优点
1代码复用性高
在抽象类中定义的模板方法和一些通用步骤可以在多个子类中复用避免了代码的重复编写。例如在一个游戏开发中游戏角色的移动和攻击行为可能有共同的流程结构通过模板方法模式可以把这个共同的流程提取出来不同类型的角色如战士、法师可以复用这个流程只需要实现自己特定的移动和攻击方式即可。
2可维护性好
由于算法的结构在抽象类中已经定义好当需要对整体算法流程进行修改时只需要在抽象类中修改模板方法的实现而不需要在每个具体子类中进行修改。比如在一个文件读取处理的系统中如果要改变文件读取后的处理流程顺序只需要在抽象的文件处理类的模板方法中调整步骤顺序而各个具体文件类型如文本文件、二进制文件的处理子类可以保持不变。
3扩展性强
可以很方便地通过创建新的子类来扩展系统功能。新的子类可以选择性地重写模板方法中的步骤以实现新的行为。例如在一个图形绘制系统中已经有了绘制基本图形如圆形、矩形的类当需要添加一种新的图形如三角形时只需要创建一个新的子类重写绘制图形的具体步骤而整体的图形绘制流程如打开画布、选择颜色、绘制图形、关闭画布可以复用已有的模板方法。
四、缺点
可能会导致类的层次结构复杂因为需要创建抽象类和多个子类来实现模板方法模式所以如果设计不当可能会导致类的层次结构过于复杂增加代码的理解和维护难度。 不符合开闭原则的部分情况虽然模板方法模式在一定程度上符合开闭原则对扩展开放对修改关闭但如果要对模板方法本身进行修改可能会影响到所有的子类。例如在模板方法中增加或删除一个步骤可能需要在所有子类中进行相应的调整。
五、使用场景
多个子类有共同的算法流程但某些步骤的实现细节不同比如在一个订单处理系统中线上订单和线下订单的处理流程都包括接收订单、处理支付、安排发货等步骤但线上订单和线下订单在处理支付和安排发货的具体方式上可能不同。 需要控制子类的扩展行为保证算法结构的稳定性例如在一个编译器的语法分析模块中不同编程语言的语法分析都有一个基本的流程如词法分析、语法树构建、语义检查等步骤。通过模板方法模式可以定义这个基本流程让不同编程语言的语法分析子类在这个框架内进行扩展同时保证整体的语法分析算法结构不变。
六、C 代码示例1
以下是一个简单的 C 代码示例模拟一个游戏角色攻击的模板方法模式。假设有一个抽象的 GameCharacter 类定义了游戏角色攻击的模板方法还有两个具体的角色类 Warrior 和 Mage它们分别重写了攻击的具体实现方式。
#include iostream
#include string// 抽象游戏角色类
class GameCharacter
{
public:// 模板方法定义了攻击的算法流程void attack(){std::cout The character is preparing to attack. std::endl;performAttack();std::cout The character has finished the attack. std::endl;}
protected:// 抽象方法由子类实现具体的攻击方式virtual void performAttack() 0;
};// 战士角色类
class Warrior : public GameCharacter
{
protected:void performAttack() override {std::cout 1 std::endl;std::cout 2 std::endl;std::cout The warrior swings his sword. std::endl;}
};// 法师角色类
class Mage : public GameCharacter
{
protected:void performAttack() override {std::cout The mage casts a spell. std::endl;std::cout 888 std::endl;std::cout 777 std::endl;}
};
int main()
{Warrior warrior;Mage mage;std::cout Warriors attack: std::endl;warrior.attack();std::cout Mages attack: std::endl;mage.attack();char t;std::cint;return 0;
}在上述代码中 首先定义了抽象类 GameCharacter它有一个公共的方法 attack这就是模板方法。在 attack 方法中定义了攻击行为的算法流程包括准备攻击、执行具体的攻击动作通过调用纯虚函数 performAttack和完成攻击。performAttack 函数是一个纯虚函数需要在子类中实现。 然后定义了两个具体的子类 Warrior 和 Mage它们都继承自 GameCharacter。在这两个子类中分别重写了 performAttack 函数实现了战士挥舞剑和法师释放法术的不同攻击方式。 在 main 函数中创建了 Warrior 和 Mage 类型的对象并分别调用它们的 attack 方法这样就会按照模板方法中定义的流程执行攻击行为每个角色会执行自己特有的攻击动作。
七、 C 代码示例2
#includeiostream
using namespace std;//抽象类
//在父类中定义操作的算法骨架而具体的实现由子类完成
class resume
{
protected:virtual void setedu(){}virtual void setage(){}virtual void setexp(){}
public:void setinformation()//骨架{setedu();setage();setexp();}
};
//子类
class xiaoming:public resume
{void setedu(){cout清华大学endl;}//具体实现void setage(){cout19岁endl;}//具体实现
};
class xiaoli:public resume
{void setedu(){cout北京大学endl;}//具体实现void setage(){cout10岁endl;}//具体实现void setexp(){cout腾讯科技endl;}
};
int main()
{resume *s1 new xiaoming();s1-setinformation();coutendlendl;resume *s2 new xiaoli();s2-setinformation();char t;std::cint;return 0;
}