当前位置: 首页 > news >正文

C++设计模式---模板方法模式

文章目录

  • 模板方法模式的作用
  • 具体的定义方式
  • 具体的应用情景


模板方法模式的作用

在固定步骤确定的情况下,通过多态机制在多个子类中对每个步骤的细节进行差异化实现。

比如一个到餐馆吃饭的流程:点餐(粤菜,鲁菜)->吃饭->结账(现金,微信),不同的人在各个环节都有不同的动作,但流程是一样的,此时就可以采用多态实现这种差异化。


具体的定义方式

父类中定义了一个操作中的算法的骨架(稳定部分),而将一些步骤延迟到子类中去实现(比如父类中定义虚函数,子类中重写虚函数)。

通过这样的方式,达到在整体稳定的情况下,能够产生一些变化的目的。

模板方法模式也被认为导致了一种反向控制结构,这种结构也被称为好莱坞法则,也就是不用来调用我,我会去调用你的,即父类调用了子类的函数。


具体的应用情景

假设你现在是一名游戏程序员,游戏策划想让你实现一个战士类,这个类有生命、魔法、攻击力等属性,并且有一个“燃烧的技能”,能够让所有敌人掉血,但是自己也会掉血,你可以这样实现:

#include<iostream>
using namespace std;

class Warrior {
public:
	Warrior(int life,int magic,int attack)
		:m_life(life)
		,m_magic(magic)
		,m_attack(attack){}

	//燃烧技能
	void JN_Burn()
	{
		cout << "让所有敌人每人失去500生命,相关逻辑代码略过。。。" << endl;
		cout << "主角自身失去300生命" << endl;
		m_life -= 300;
		cout << "播放燃烧技能的动画" << endl;
	}
private:
	//角色属性
	int m_life;//生命
	int m_magic;//魔法值
	int m_attack;//攻击力
};

int main()
{
	Warrior morleobj(1000, 0, 200);
	morleobj.JN_Burn();//释放燃烧技能
}

现在游戏策划又想让你实现一个“法师”类,这个类和战士类的成员属性一样,唯一的不同是“燃烧”技能不会让自己掉血而是掉魔法值。并且策划告诉你,每个类都有一个“燃烧”技能。

你发现“法师”类和“战士”类大部分代码是相同的,那此时你直接实现一个“战斗者”的抽象类,让“战士”类和“法师”类继承“战斗者”类。

#include<iostream>
using namespace std;
//抽象类
class Fighter {
public:
	Fighter(int life, int magic, int attack)
		:m_life(life)
		, m_magic(magic)
		, m_attack(attack) {}
	virtual ~Fighter() {}

	//燃烧技能
	void JN_Burn()
	{
		effect_enemy();//对敌人产生影响
		effect_self();//对自身产生影响
		play_effect();//播放“燃烧”技能特效,由于经费不足,这个技能特效所有类都相同
	}
private:
	virtual void effect_enemy() = 0;
	virtual void effect_self() = 0;
	void play_effect() 
	{
		//实现“燃烧”特效
		cout << "播放燃烧技能的特效,由于经费不足,这个技能特效所有类都相同,不需要虚函数" << endl;
	}

protected://因为可能会被子类访问,所以不使用private
	//角色属性
	int m_life;//生命
	int m_magic;//魔法值
	int m_attack;//攻击力
};
//战士类
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;
	}
};
//法师类
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;
	}
};

int main()
{
	Fighter* p1 = new F_Warrior(1000, 0, 200);
	Fighter* p2 = new F_Mage(5000, 500, 300);

	//战士和法师释放燃烧技能
	p1->JN_Burn();
	cout << "----------------" << endl;
	p2->JN_Burn();
}

在这里插入图片描述

上面的代码已经引入了“模板方法模式”,不同的类通过父类指针调用同一个函数JN_Burn,由于多态机制,子类重写了JN_Burn中的虚函数。
JN_Burn这个函数中调用的函数数量和顺序总是固定的,因此这个函数就可以称为“模板”。

至此不同的子类产生了不同的效果,但所有子类的执行流程完全相同。
在这里插入图片描述

相关文章:

  • 数据结构和算法——绪论
  • 最小生成树算法的相关变形题
  • Android中常用的几种容器视图的使用
  • 随手记面试录
  • VMware软件下载安装以及在VMware中安装Centos-stream
  • JCL入门教程
  • 5.6如何寻找最长回文子串
  • tkinter-event事件
  • Windows10环境gradle安装与配置
  • DELMIA弧焊虚拟仿真:带变位机的机器人弧焊焊接程序自动生成方法
  • Redis 非关系型数据库学习(三)---- Redis 基础知识
  • 离线数仓(2):数据仓库相关架构和规范
  • MySQL-数据类型和DDL
  • Linux学习笔记6 - 系统启动流程
  • 动态数组写模板类
  • hexo+github搭建个人博客
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Apache Pulsar 2.1 重磅发布
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Invalidate和postInvalidate的区别
  • IP路由与转发
  • jdbc就是这么简单
  • SpringBoot 实战 (三) | 配置文件详解
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 基于 Babel 的 npm 包最小化设置
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 目录与文件属性:编写ls
  • 扑朔迷离的属性和特性【彻底弄清】
  • 前端学习笔记之观察者模式
  • 前端知识点整理(待续)
  • 用Python写一份独特的元宵节祝福
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • #Z2294. 打印树的直径
  • $jQuery 重写Alert样式方法
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (办公)springboot配置aop处理请求.
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (论文阅读11/100)Fast R-CNN
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (四)Linux Shell编程——输入输出重定向
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转)mysql使用Navicat 导出和导入数据库
  • .bat批处理(一):@echo off
  • .net解析传过来的xml_DOM4J解析XML文件
  • .php文件都打不开,打不开php文件怎么办
  • @Repository 注解
  • @RequestMapping用法详解
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
  • [Angular 基础] - 自定义指令,深入学习 directive
  • [BZOJ 3282] Tree 【LCT】