Loading... > 模板模式主要是用来解决复用和扩展两个问题。 模板方法和回调应用场景是一致的,都是定义好算法骨架,并对外开放扩展点,符合开闭原则。 模板方法是通过继承来实现,是自己调用自己;回调是类之间的组合。 # 一、定义: 模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。这里的`“算法”,我们可以理解为广义上的“业务逻辑”`。 在模板模式经典的实现中,模板方法定义为 final,可以避免被子类重写。需要子类重写的方法定义为纯虚函数 virtual,可以强迫子类去实现。 # 1、模板模式作用一:复用 > 在固定步骤确定的情况下,通过多态机制在多个子类中对每个步骤的细节进行差异化实现,这就是模板方法模式能够达到的效果。 模板模式把一个算法中不变的流程抽象到父类的模板方法 templateMethod() 中,将可变的部分 method1()、method2() 留给子类 ContreteClass1 和 ContreteClass2 来实现。所有的子类都可以复用父类中模板方法定义的流程代码。我们通过两个小例子来更直观地体会一下。 ```cpp //战斗者父类 class Fighter { public: Fighter(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {} virtual ~Fighter() {} //做父类时析构函数应该为虚函数 //对主角自身会产生影响,对敌人会产生影响。 //分析:对敌人产生影响,有函数effect_enemy。对主角自身产生影响,有函数effect_self。播放技能play_effect函数。 void JN_Burn() //技能“燃烧” { effect_enemy(); //对敌人产生的影响 effect_self(); //对主角自身产生的影响 play_effect(); //播放技能“燃烧”的技能特效 } private: virtual void effect_enemy() {} //函数体为空,表示啥也不做,如果要求必须在子类中重新实现该虚函数,则可以将该函数写成纯虚函数。 virtual void effect_self() {} void play_effect() { cout << "播放技能\\"燃烧\\"的技能特效给玩家看" << endl; //所有主角播放的技能特效都相同,因此不用写成一个虚函数并在子类中实现技能特效的播放。 } protected: //可能被子类访问,所以用protected修饰 //角色属性 int m_life; //生命值 int m_magic; //魔法值 int m_attack; //攻击力 }; 子类: //“战士”类,父类为Fighter class F_Warrior :public Fighter { public: F_Warrior(int life, int magic, int attack) :Fighter(life,magic,attack) {} private: //对敌人产生的影响 virtual void effect_enemy() { cout << "战士主角_让所有敌人每人失去500点生命,相关逻辑代码这里略......" << endl; } //对主角自身产生的影响 virtual void effect_self() { cout << "战士主角_自身失去300点生命值" << endl; m_life -= 300; } }; //------------------------- //“法师”类,父类为Fighter class F_Mage :public Fighter { public: F_Mage(int life, int magic, int attack) :Fighter(life, magic, attack) {} private: //对敌人产生的影响 virtual void effect_enemy() { cout << "法师主角_让所有敌人每人失去650点生命,相关逻辑代码这里略......" << endl; } //对主角自身产生的影响 virtual void effect_self() { cout << "法师主角_自身失去100点魔法值" << endl; m_magic -= 100; } }; ``` 模板方法模式的定义(实现意图):定义了一个操作中的算法的骨架(稳定部分 JN\_Burn),而将一些步骤延迟到子类中去实现(父类中定义虚函数,子类中实现/重写这个虚函数),从而达到在整体稳定的情况下能够产生一些变化的目的。 晚绑定: 早绑定: ## UML图  # 2、模板模式作用二:扩展 > 框架提供一个扩展点,让框架用户在不用修改框架源码的情况下,将业务代码通过扩展点镶嵌到框架中执行。 比如gTest中的单元测试中的,setUp()以及tearDown()扫尾工作。具体流程是setUp() —> runTest() —> tearDown() 尽管 setUp()、tearDown() 并不是抽象函数,还提供了默认的实现,不强制子类去重新实现,但这部分也是可以在子类中定制的,所以也符合模板模式的定义。 最后修改:2025 年 07 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏