Head First设计模式——策略模式

2023-10-27

 

 

Head First设计模式》是一本介绍设计模式的书籍,书中的设计模式主要是用Java语言进行实现,由于本人对C++比较熟悉,因此在阅读这本书籍时,尽自己所能,用C++重新去实现书中所涉及到的设计模式。若有错误或需要进一步讨论之处,望阅览者不吝赐教!

策略模式——定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变换独立于使用算法的客户。

需求:一家公司需要设计一款模拟鸭子游戏的电子软件。游戏中会出现各种鸭子,比如橡皮鸭、诱饵鸭、鸭等,这些鸭子会有不同的行为,比如有的会叫、有的不会叫、有的会飞、有的不会飞等。为了适应不同的鸭子对象和鸭子行为,可以用策略模式进行整个框架的构建。

1、设计一个鸭子类Duck,一个飞行行为接口类(C++里面没有接口的的说法,这里套用Java里的说法,更容易理解)FlyBehavior,一个叫声接口类QuackBehavior,这是第一个设计模式,所以没有考虑周全,将这三个类放到了一个.h文件里;一般而言,应该分开为三个.h文件。Duck.h、Duck.cpp文件具体代码如下:

#pragma once
#include<iostream>
using namespace std;

class FlyBehavior;
class QuackBehavior;

class CDuck
{
public:
	CDuck();
	~CDuck();

	virtual void display() {}
	virtual void performFly();
	virtual void performQuack();

	void setFlyBehavior(FlyBehavior *fb);
	void setQuackBehavior(QuackBehavior *qb);
	void swim();

protected:
	FlyBehavior* flyBehavior;
	QuackBehavior* quackBehavior;
};

class FlyBehavior
{
public:
	FlyBehavior() {}
	~FlyBehavior() {}

	virtual void fly() {}
private:

};

class QuackBehavior
{
public:
	QuackBehavior() {}
	~QuackBehavior() {}

	virtual void quack(){}
private:

};

class FlyWithWings:public FlyBehavior      //第一个具体飞行行为类
{
public:
	FlyWithWings() {}
	~FlyWithWings() {}
	void fly()
	{
		cout << "I'm flying!!" << endl;
	}
private:

};

class FlyNoWay :public FlyBehavior   //第二个具体飞行行为类
{
public:
	FlyNoWay() {}
	~FlyNoWay() {}
	void fly()
	{
		cout << "I can't fly!!" << endl;
	}
private:

};

class FlyRocketPowered:public FlyBehavior  //第三个具体飞行行为类
{
public:
	FlyRocketPowered(){}
	~FlyRocketPowered(){}

	void fly()
	{
		cout << "I'm flying with rocket!!" << endl;
	}

private:

};

class Quack:public QuackBehavior      //第一个具体叫声类
{
public:
	Quack() {}
	~Quack() {}

	void quack()
	{
		cout << "Quack" << endl;
	}
private:

};

class MuteQuack :public QuackBehavior  //第二个具体叫声类
{
public:
	MuteQuack() {}
	~MuteQuack() {}

	void quack()
	{
		cout << "<< Silence >>" << endl;
	}
private:

};

class Squeak :public QuackBehavior  //第三个具体叫声类
{
public:
	Squeak() {}
	~Squeak() {}

	void quack()
	{
		cout << "Squeak" << endl;
	}
private:

};



#include "Duck.h"

CDuck::CDuck()
{
}

CDuck::~CDuck()
{
}

void CDuck::performFly()
{
	flyBehavior->fly();
}

void CDuck::performQuack()
{
	quackBehavior->quack();
}

void CDuck::swim()
{
	cout << "All ducks float,even decoys!!" << endl;
}

void CDuck::setFlyBehavior(FlyBehavior* fb)
{
	flyBehavior = fb;
}

void CDuck::setQuackBehavior(QuackBehavior *qb)
{
	quackBehavior = qb;
}

2、创建两个具体鸭子类:MallardDuck、ModelDuck,MallardDuck.h、MallardDuck.cpp、ModelDuck.h、ModelDuck.cpp文件具体代码如下:

#pragma once
#include "Duck.h"
class CMallardDuck :public CDuck
{
public:
	CMallardDuck();
	~CMallardDuck();

	void display();
};
#include "MallardDuck.h"

CMallardDuck::CMallardDuck()
{
	quackBehavior = new Quack();
	flyBehavior = new FlyWithWings();
}

CMallardDuck::~CMallardDuck()
{

}

void CMallardDuck::display()
{
	cout << "I'm a real Mallard duck!!" << endl;
}
#pragma once
#include "Duck.h"
class CModelDuck :
	public CDuck
{
public:
	CModelDuck();
	~CModelDuck();
	void display();
};

#include "ModelDuck.h"



CModelDuck::CModelDuck()
{
	flyBehavior = new FlyNoWay();
	quackBehavior = new Quack();
}


CModelDuck::~CModelDuck()
{
}

void CModelDuck::display()
{
	cout << "I'm a model duck!!" << endl;
}

3、测试代码和结果如下:

/*
策略模式:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让
算法的变化独立于使用算法的客户
*/
#include "Duck.h"
#include "MallardDuck.h"
#include "ModelDuck.h"

int main()
{
	CDuck* mallard = new CMallardDuck();
	mallard->performFly();
	mallard->performQuack();

	CDuck* model = new CModelDuck();
	model->performFly();
	model->setFlyBehavior(new FlyRocketPowered());
	model->performFly();

	delete mallard;
	delete model;
	return 0;
}

在讲述策略模式时,书中涉及到了三个OO原则:

1、封装变化,即将框架中易于变化的部分抽象出来,形成独立的类;

2、多用组合,少用继承,即类与类之间尽量处于合作关系,而不是依赖关系;

3、针对接口编程,不针对具体实现编程,即对接口编程,当需要进行变动时,只需变动接口即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Head First设计模式——策略模式 的相关文章

随机推荐

  • printf(“%d,%d\n“,i--,i++)

    sample cpp include
  • Windows 下创建定时任务执行Python脚本

    文章目录 一 环境 二 脚本 三 创建定时任务 1 打开 任务计划程序 2 打开 创建任务 窗口 3 创建任务一一常规 4 创建任务一一触发器 5 创建任务一一操作 6 创建任务一一条件 7 创建任务一一设置 8 完成任务创建 四 验证定时
  • 记录自己在结构光三维重建领域的学习过程(一)

    仿真数据集与真是数据集之间差异较大 二者的网络均不可完美预测另一种数据 寻找解决办法 首先确定是不是数据的问题 阅读论文 Light field structured light projection data generation wit
  • 关于存储过程中SQL语句IN条件传参注意说

    背景说明 在数据库操作中我们经常会用到查询语句 在一些情况下 需要使用到IN条件 正常的查询中IN需要注意的是最好in中的参数不能超过1000个 超过1000的时候oracle会抛出异常 这个如何处理先不提 这次要说的是 如果在存储过程中使
  • 某单位分配到一个地址块 136.23.12.64/26。现在需要进一步划分为4个一样大的子网。试问:

    1 每个子网的网络前缀有多长 2 每个子网中有多少个地址 3 每个子网的地址块是什么 4 每一个子网可分配给主机使用的最小地址和最大地址是什么 姐
  • JS中的邮箱验证

    通过js在前端对用户输入进行校验 即可以产生较好的交互体验 也可以减轻后台的压力 邮箱的基本格式要求 1 只能以单词字符开头 即a z A Z 0 9 2 只能有一个 3 后面有一个到多个点 并且点不能在最后 4 特殊字符不能开头和结尾 使
  • 数据存储,详细讲解

    数据存储 详细讲解 数据类型的介绍 整形的内存存储 大小端介绍 浮点数的存储 数据类型的介绍 1 内置类型 char 字符数据类型 1 short 短整型 2 int 整形 4 long 长整型 4 8 long long 更长的整形 8
  • matlab之数组反序输出

    a 1 2 3 4 5 a end 1 1 5 4 3 2 1 转载于 https www cnblogs com yibeimingyue p 11201805 html
  • 高阶数据结构之并查集

    文章目录 并查集 并查集的常规实现 并查集的简化实现 算法题 模板 朴素的并查集 维护size的并查集 维护到祖宗节点的并查集 并查集 在某些应用问题中 需要将n个不同的元素划分成一些不想交的集合 开始时 每个元素自成一个单元集合 然后按照
  • 一文搞懂状态模式

    原理 状态机有三个组成部分 状态 事件 动作 遇到不同的事件会触发状态的转移和动作的执行 不过动作不是必须的 可能只有状态的转移 没有动作的执行 状态模式的目的就是实现状态机 案例带入 比如 超级马里奥 在游戏中 马里奥可以变身为多种形态
  • 抖音究竟对线下生意有没有价值?

    戳上方增长黑盒Growthbox点亮星标 深度研究不错过 主笔 邹小困 研究员 彬超 Emma 出品 增长黑盒研究组 01 防火防盗防抖音 互联网世界的后起之秀字节跳动 如同进击的巨人 在短短几年内就已将业务的触角伸向各个领域 图为chat
  • Java基础(IO输入输出流,读写文件操作,对象序列化)

    IO 输入输出流基本概念 输入流 信息从程序空间之外的地方流入程序空间里面 输出流 信息从程序空间里面流到程序空间之外的地方 输入输出流的分类 从流的方法划分 输入流 输入流 从流的分工划分 节点流 访问文件进行输入输出操作的流 处理流 在
  • IDEA常见错误:程序包org.apache.commons.xxx不存在

    具体错误 Could not transfer artifact org apache commons commons text pom 1 1 from to Nexus Repository Nexus Repository Manag
  • 全新【Photoshop 2022 for mac】中文版发布下载 支持M1 M1X M2处理器 详细安装教程

    Adobe PhotoShop 2022 for mac 23 0 是 Adobe 2022 中最重要的组成软件之一 PhotoShop主要用来处理图像 是行业内最流行的图像处理软件 ps 2022 更加智能化和强大 Adobe Photo
  • CAN db++(创建DBC文件)学习笔记

    CAN db 学习笔记 1 新建文件 2 模块介绍 3 建立DBC的过程 自下而上 信号 报文 节点 1 信号 2 报文 3 建立报文与信号的关系 4 建立信号在报文里的位置 因为前面定义了报文的数据长度 且把信号放到了报文里面 那么信号在
  • 【Linux_CentOS7】 systemctl restart named报错-Job for named.service failed because the control process

    14天阅读挑战赛 努力是为了不平庸 算法学习有些时候是枯燥的 这一次 让我们先人一步 趣学算法 欢迎记录下你的那些努力时刻 算法学习知识点 算法题解 遇到的算法bug 等等 在分享的同时加深对于算法的理解 同时吸收他人的奇思妙想 一起见证技
  • Taro+vue3小程序开启分享他人和分享到朋友圈

    import Taro useShareAppMessage useShareTimeline from tarojs taro onMounted gt Taro showShareMenu withShareTicket true me
  • 有趣的java代码_求一些有趣的java小程序?

    不请自来 用eclipse写的一个输出爱心的小程序 应该算是比较有趣的吧 下面是程序内容 public class love public static void main String args TODO Auto generated m
  • BeanUtils.copyProperties的用法(超详细,建议收藏)

    常见场景 我们如果有两个具有很多相同属性名的JavaBean对象a和b 想把a中的属性赋值到b 例如 接口中将接收到的前端请求参数XxxReqVo 我们想把这个入参转化为XxxQuery对象作为数据库的查询条件对象 传统做法是手动set 即
  • Head First设计模式——策略模式

    Head First设计模式 是一本介绍设计模式的书籍 书中的设计模式主要是用Java语言进行实现 由于本人对C 比较熟悉 因此在阅读这本书籍时 尽自己所能 用C 重新去实现书中所涉及到的设计模式 若有错误或需要进一步讨论之处 望阅览者不吝