2.策略模式

news2025/1/12 12:02:23

UML图

在这里插入图片描述

代码

main.cpp

#include "Strategy.h"
#include "Context.h"

void test()
{
	Context* pContext = nullptr;
	
	/* StrategyA */
	pContext = new Context(new StrategyA());
	pContext->contextInterface();

	/* StrategyB */
	pContext = new Context(new StrategyB());
	pContext->contextInterface();

	/* StrategyC */
	pContext = new Context(new StrategyC());
	pContext->contextInterface();

	delete pContext;
	pContext = nullptr;
}

int main()
{
	test();
	system("pause");
}

Strategy.h

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

/*
策略模式:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的用户。
*/

/* 抽象策略基类:定义所有支持算法的公共接口 */
class Strategy
{
public:
	virtual void algorithmInterface() = 0;
};

/* 策略A */
class StrategyA :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法A实现" << endl;
	}
};

/* 策略B */
class StrategyB :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法B实现" << endl;
	}
};

/* 策略C */
class StrategyC :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法C实现" << endl;
	}
};

Context.h

#pragma once
#include "Strategy.h"

/*
笔者感受:使用类C操控类A继承体系A1,A2,A3中公有对外暴露接口。
利用一个额外的类,(1)将strategy抽象策略基类,作为额外类的入参;
(2)将strategy抽象策略基类作为额外类的成员变量,利用多态原理,接收外面传来的具体抽象策略。
(3)对外暴露的接口中,使用成员变量抽象策略基类,调用策略继承体系中的子类们都需要继承的纯虚函数接口。
即可,使用额外类操控策略继承体系中公有对外暴露的接口了。
*/
class Context
{
public:
	Context(Strategy* pStrategy) :m_pStrategy(pStrategy) {}
	void contextInterface();
private:
	Strategy* m_pStrategy{ nullptr };
};

void Context::contextInterface()
{
	m_pStrategy->algorithmInterface();
}


策略模式+简单工厂

  • 优点:策略模式+简单工厂:可以完全将策略继承体系与用户端完全剥离开来,将策略继承体系完全封装起来,对用户完全不可见。
  • 总结
    • 类C通过没什么信息含量的枚举作为入参,利用简单工厂生成类A继承体系中的各子类A1、A2、A3。同时,用基类A作为类C的成员变量,接一下刚生成的类A的子类。
    • 类C对外统一暴露一个接口,该接口中,类C的成员变量类A调用继承体系公有对外暴露的接口func()。

main.cpp

#include "StrategyFactory.h"

/*
策略方法+简单工厂:可以将策略继承体系完全剥离开来,完全封装起来,对用户完全不可见。
*/

void test()
{
	StrategyFactory* pStrategyFactory = nullptr;
	
	/* StrategyA */
	pStrategyFactory = new StrategyFactory(StrategyType::eStrategyA);
	pStrategyFactory->contextInterface();

	/* StrategyB */
	pStrategyFactory = new StrategyFactory(StrategyType::eStrategyB);
	pStrategyFactory->contextInterface();

	/* StrategyC */
	pStrategyFactory = new StrategyFactory(StrategyType::eStrategyC);
	pStrategyFactory->contextInterface();

	delete pStrategyFactory;
	pStrategyFactory = nullptr;
}

int main()
{
	test();
	system("pause");
}

Strategy.h

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

/*
策略模式:定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的用户。
*/

/* 抽象策略基类:定义所有支持算法的公共接口 */
class Strategy
{
public:
	virtual void algorithmInterface() = 0;
};

/* 策略A */
class StrategyA :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法A实现" << endl;
	}
};

/* 策略B */
class StrategyB :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法B实现" << endl;
	}
};

/* 策略C */
class StrategyC :public Strategy
{
public:
	virtual void algorithmInterface()override
	{
		cout << "算法C实现" << endl;
	}
};

StrategyFactory.h

#pragma once
#include "Strategy.h"

/*
我的感受:使用类C操控类A继承体系A1,A2,A3中公有对外暴露接口。
利用一个额外的类,(1)将strategy抽象策略基类,作为额外类的入参;
(2)将strategy抽象策略基类作为额外类的成员变量,利用多态原理,接收外面传来的具体抽象策略。
(3)对外暴露的接口中,使用成员变量抽象策略基类,调用策略继承体系中的子类们都需要继承的纯虚函数接口。
即可,使用额外类操控策略继承体系中公有对外暴露的接口了。
*/
enum StrategyType
{
	eStrategyA,
	eStrategyB,
	eStrategyC
};

class StrategyFactory
{
public:
	StrategyFactory(StrategyType nType);
	~StrategyFactory();
	void contextInterface();
private:
	Strategy* m_pStrategy{ nullptr };
};

StrategyFactory::StrategyFactory(StrategyType nType)
{
	switch (nType)
	{
	case eStrategyA:
		m_pStrategy = new StrategyA();
		break;
	case eStrategyB:
		m_pStrategy = new StrategyB();
		break;
	case eStrategyC:
		m_pStrategy = new StrategyC();
		break;
	}
}

StrategyFactory::~StrategyFactory()
{
	delete m_pStrategy;
	m_pStrategy = nullptr;
}

void StrategyFactory::contextInterface()
{
	m_pStrategy->algorithmInterface();
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1017013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MybatisPlus(5)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 上篇讲了增删的操作&#xff0c;这篇讲修改操作中的一个问题以及它对应的…

002-第一代硬件系统架构确立及产品选型

第一代硬件系统架构确立及产品选型 文章目录 第一代硬件系统架构确立及产品选型项目介绍摘要硬件架构硬件结构选型及设计单片机选型上位机选型扯点别的 关键字&#xff1a; Qt、 Qml、 信号采集机、 数据处理、 上位机 项目介绍 欢迎来到我们的 QML & C 项目&#xff…

Centos8下载安装JDK8

安装JDK8 一、下载 官网&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8-linux 二、存放到opt目录下 三、解压 tar -zxvf jdk-8u361-linux-x64.tar.gz -C /usr/local如果下载的是tar格式&#xff0c;则安装如下命令解压 tar -zvf jdk-8u361-linu…

Flash的学习

Flash的学习 1 概述 2 特性 STM32 的内部FLASH 包含主存储器、系统存储器以及选项字节区域。 2.1 主存储器 主存储器分为256 页&#xff0c;每页大小为2KB&#xff0c;共512KB。这个分页的概念&#xff0c;实质就是FLASH 存储器 的扇区&#xff0c;与其它FLASH 一样&…

【C++】动态内存管理(79分钟写的文章哪里看不懂了,快来学)

动态内存管理目录&#xff1a; 一、C/C内存分布 在学习了C/C内存区域的划分后&#xff0c;我们来做几道题巩固一下&#xff1a; 1. 选择题&#xff1a;选项 : A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)globalVar在哪里&#xff1f;____ staticGlobalVar在哪里&#x…

【2023知乎评论爬虫】我用Python爬虫爬了2386条知乎评论!

文章目录 一、爬取目标二、展示爬取结果三、爬虫代码讲解3.1 分析知乎页面3.2 爬虫代码 四、同步视频五、完整源码 您好&#xff0c;我是 马哥python说&#xff0c;一枚10年程序猿。 一、爬取目标 前些天我分享过一篇微博的爬虫&#xff1a;https://blog.csdn.net/solo_msk/a…

Spring 的注入

目录 一、注入&#xff08;Injection&#xff09; 1、什么是注入 &#xff08;1&#xff09;为什么需要注入 &#xff08;2&#xff09;如何进行注入 2、Spring 注入原理分析&#xff08;简易版&#xff09; 二、Set 注入详解 1、JDK 内置类型 &#xff08;1&#xff09…

【修复版】2023新版塔罗 算八字测运易理风水 取名 源码平台 搭建教程

全线修复&#xff0c;欢迎你拿其他家的来比&#xff0c;叫他们发测试连接去测试对比&#xff0c;眼睛骗不了人 很多说自家的是修复版&#xff0c;能像我这样把修复的列出来嘛&#xff0c;顾客朋友也可以直接去问他&#xff1a;你到底修复了个啥&#xff1f;&#xff1f;&#…

深入探索智能问答:从检索到生成的技术之旅

目录 一、智能问答概述1. **语义理解**2. **知识库和数据库**3. **上下文感知**4. **动态学习和自适应** 二、发展历程1. **基于规则的系统**2. **统计方法的兴起**3. **深度学习和神经网络的突破**4. **预训练模型** 三、智能问答系统的主要类型四、基于知识库的问答系统五、基…

如何使用记事本制作一个简陋的小网页(1)

1、创建一个记事本 2、将记事本的尾缀进行修改&#xff0c;变为html html本质上是一种标签并不是一种语言&#xff0c;其最主要的功能就是对页面设置和页面的文本样式进行修改和修缮。 3、右键被修改了尾缀的文本&#xff0c;选择使用记事本的打开方式。 打开完毕后&#xf…

什么是JavaScript的事件驱动编程(event-driven programming)?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 事件&#xff08;Event&#xff09;⭐ 事件监听器&#xff08;Event Listener&#xff09;⭐ 回调函数&#xff08;Callback Function&#xff09;⭐ 非阻塞和异步⭐ 事件循环&#xff08;Event Loop&#xff09;⭐ 触发事件&#xff08;…

「C++程序设计 (面向对象进阶)」学习笔记・二

0、引言 本专栏的系列文章是在学习 北京邮电大学 崔毅东 老师的《C程序设计 (面向对象进阶)》课程过程中整理的。欢迎前往专栏了解更多相关内容~ &#x1f600; 有关于现代 C 的基本介绍&#xff0c;请前往《现代C基本介绍》&#xff01; &#x1f514; 先决条件 本专栏的系列…

【测试开发】答疑篇 · 什么是软件测试

【测试开发】答疑篇 文章目录 【测试开发】答疑篇1. 生活中的测试2. 什么是软件测试3. 为什么要有测试/没有测试行不行4. 软件测试和软件开发的区别5. 软件测试和软件调试之间的区别6. 软件测试的岗位7. 优秀测试人员具备的素质 【测试开发】答疑篇 软件不一定是桌面应用&#…

公众号迁移线上公证如何办?

公众号账号迁移的作用是什么&#xff1f;只能变更主体吗&#xff1f;微信公众平台的帐号迁移功能可将原公众号的粉丝、文章素材、违规记录、留言功能、名称等迁移至新的公众号。通过迁移可以实现公众号的公司主体变更、粉丝转移、开通留言功能、服务号转为订阅号等作用。因此不…

Qt基于paintEvent自定义CharView

Qt基于paintEvent自定义CharView 鼠标拖动&#xff0c;缩放&#xff0c;区域缩放&#xff0c; 针对x轴&#xff0c;直接上代码 charview.h #ifndef CHARVIEW_H #define CHARVIEW_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #inclu…

Kotlin使用infix关键字构建高可读性代码

自从Google推出Kotlin作为官方开发语言后&#xff0c;一堆像我这样的习惯Java开发的程序员从不习惯到爱上这门语言只用了很短的时间&#xff0c;相比于Java语言&#xff0c;kotlin集各家所长&#xff0c;可以使用更少的代码&#xff0c;实现更多更复杂的需求&#xff0c;而且可…

腾讯mini项目-【指标监控服务重构】2023-08-18

今日已办 watermill 将 key 设置到 message 中 修改 watermill-kafka 源码 将 key 设置到 message.metadata中 接入 otel-sdk 添加 middleware resolveUpstreamCtx 解析上游上下文&#xff0c;开启根Span添加 middleware middleware.InstantAck - 马上ACK&#xff0c;使得多…

怒刷LeetCode的第4天(Java版)

#【中秋征文】程序人生&#xff0c;中秋共享# 目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;遍历字符串 方法二&#xff1a;有限状态机&#xff08;Finite State Machine&#xff09; 方法三&#xff1a;正则表达式 第二题 题目来源 题目内容 解决方…

机器学习——决策树/随机森林

0、前言&#xff1a; 决策树可以做分类也可以做回归&#xff0c;决策树容易过拟合决策树算法的基本原理是依据信息学熵的概念设计的&#xff08;Logistic回归和贝叶斯是基于概率论&#xff09;&#xff0c;熵最早起源于物理学&#xff0c;在信息学当中表示不确定性的度量&…

带你了解前后端分离的秘密-Vue【vue入门】

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Vue》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这个专栏…