设计模式:策略模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介:

策略模式,它是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换。策略模式让算法的变化独立于使用算法的客户,降低了耦合,增加了系统的可维护性和可扩展性。

策略模式的结构包括三种角色:
1、策略(Strategy):策略是一个接口,该接口定义了算法标识。
2、具体策略(ConcreteStrategy):具体策略是实现策略接口的类,具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体算法。
3、上下文(Context):上下文是依赖于策略接口的类,即上下文包含有策略声明的变量。上下文中提供了一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法。

策略模式的使用场景:
1、针对同一类型问题的多种处理方式,但具体行为有差别时。
2、需要安全地封装多种同一类型的操作时。
3、出现同一抽象类有多个子类,而又需要使用 if-else 或者 switch-case 来选择具体子类时。
4、当业务功能是客户程序的一个难以分割的成分时,增加新的业务算法或改变现有算法将十分困难。
5、当不同的时候需要不同的算法,我们不想支持我们并不使用的业务算法时。
6、当算法使用了客户不应该知道的数据时。
7、当一个类定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现时。

总之,策略模式是一种非常实用的设计模式,可以用于封装各种类型的规则,并且可以在不同的时间应用不同的业务规则。

策略模式的创建步骤:
1、定义策略接口:首先需要定义一个策略接口,该接口中包含算法的方法。
2、创建具体策略类:根据策略接口,创建实现具体算法的类。
3、创建上下文类:上下文类负责维护和查询策略对象,并在具体策略类中注入策略对象。
4、在上下文类中注入策略对象:通过构造函数或者setter方法,将策略对象注入到上下文类中。
5、在客户端中创建上下文对象:在客户端中创建上下文对象,并将具体策略对象注入到上下文对象中。
6、客户端调用上下文对象:客户端通过上下文对象调用具体策略对象的方法,实现算法的调用。

以上是策略模式的基本创建步骤,具体实现方式可能会因语言和需求而有所不同。

策略模式的优点,主要包括:
1、提供了对“开闭原则”的完美支持,可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
2、提供了管理相关的算法族的办法,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
3、提供了可以替换继承关系的办法,使得系统更加灵活和可维护。
4、使用策略模式可以避免使用多重条件转移语句,如 if...else 语句、switch...case 语句。
5、可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的实现方式。

策略模式的缺点,主要包括:
1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类,这可能违反了“开闭原则”。
2、策略模式会造成产生很多策略类,增加了系统的复杂性和维护成本。
3、在实现上,策略模式需要使用继承和多态,这会增加代码的复杂性和实现的难度。
4、在使用策略模式时,需要注意策略的正确性和稳定性,因为不同的策略可能会对系统的行为产生不同的影响。

总之,策略模式虽然可以提高系统的灵活性和可维护性,但也存在一些缺点需要注意。在使用策略模式时,需要根据具体情况进行权衡和考虑。

示例:

一、C#策略模式

以下是一个示例,展示了如何在C#中实现策略模式:

//定义策略接口
public interface Strategy  
{  void Execute();  
}
//创建具体策略类
public class ConcreteStrategyA : Strategy  
{  public void Execute()  {  Console.WriteLine("执行策略A");  }  
}  public class ConcreteStrategyB : Strategy  
{  public void Execute()  {  Console.WriteLine("执行策略B");  }  
}
//创建上下文类
public class Context  
{  private Strategy strategy;  public Context(Strategy strategy)  {  this.strategy = strategy;  }  public void SetStrategy(Strategy strategy)  {  this.strategy = strategy;  }  public void DoSomething()  {  strategy.Execute();  }  
}
//在客户端中创建上下文对象并注入具体策略对象
public class Client{public void Test(){Context context = new Context(new ConcreteStrategyA());  context.DoSomething();  // 输出:执行策略A  context.SetStrategy(new ConcreteStrategyB());  context.DoSomething();  // 输出:执行策略B}
}

二、java策略模式

策略模式通常通过以下方式实现:

//定义策略接口
public interface Strategy {  void execute();  
}
//创建具体策略类
public class ConcreteStrategyA implements Strategy {  @Override  public void execute() {  System.out.println("执行策略A");  }  
}  public class ConcreteStrategyB implements Strategy {  @Override  public void execute() {  System.out.println("执行策略B");  }  
}
//创建上下文类
public class Context {  private Strategy strategy;  public Context(Strategy strategy) {  this.strategy = strategy;  }  public void setStrategy(Strategy strategy) {  this.strategy = strategy;  }  public void doSomething() {  strategy.execute();  }  
}
//在客户端中创建上下文对象并注入具体策略对象
public class Main {  public static void main(String[] args) {  Context context = new Context(new ConcreteStrategyA());  context.doSomething();  // 输出:执行策略A  context.setStrategy(new ConcreteStrategyB());  context.doSomething();  // 输出:执行策略B}
}

三、javascript策略模式

在JavaScript中,策略实现方式如下:

//定义策略接口
function Strategy(execute) {  this.execute = execute;  
}
//创建具体策略类
class ConcreteStrategyA extends Strategy {  constructor() {  super(this.execute);  }  execute() {  console.log('执行策略A');  }  
}  class ConcreteStrategyB extends Strategy {  constructor() {  super(this.execute);  }  execute() {  console.log('执行策略B');  }  
}
//创建上下文类
class Context {  constructor(strategy) {  this.strategy = strategy;  }  setStrategy(strategy) {  this.strategy = strategy;  }  doSomething() {  this.strategy.execute();  }  
}//在客户端中创建上下文对象并注入具体策略对象
const context = new Context(new ConcreteStrategyA());  
context.doSomething();  // 输出:执行策略A  
context.setStrategy(new ConcreteStrategyB());  
context.doSomething();  // 输出:执行策略B

四、C++策略模式

以下是在C++中实现策略模式:

//定义策略接口
class Strategy {  
public:  virtual void execute() = 0;  
};
//创建具体策略类
class ConcreteStrategyA : public Strategy {  
public:  void execute() override {  cout << "执行策略A" << endl;  }  
};  class ConcreteStrategyB : public Strategy {  
public:  void execute() override {  cout << "执行策略B" << endl;  }  
};
//创建上下文类
class Context {  
public:  Context(Strategy* strategy) : strategy_(strategy) {}  void setStrategy(Strategy* strategy) {  strategy_ = strategy;  }  void doSomething() {  strategy_->execute();  }  
private:  Strategy* strategy_;  
};
//在客户端中创建上下文对象并注入具体策略对象
int main() {  Context context(new ConcreteStrategyA());  context.doSomething();  // 输出:执行策略A  context.setStrategy(new ConcreteStrategyB());  context.doSomething();  // 输出:执行策略B  delete context.strategy_;  delete context;  return 0;  
}

五、python策略模式

以下是在python中实现策略模式:

//定义策略接口
from abc import ABC, abstractmethod  class Strategy(ABC):  @abstractmethod  def execute(self):  pass//创建具体策略类
class ConcreteStrategyA(Strategy):  def execute(self):  print("执行策略A")  class ConcreteStrategyB(Strategy):  def execute(self):  print("执行策略B")//创建上下文类
class Context:  def __init__(self, strategy):  self.strategy = strategy  def set_strategy(self, strategy):  self.strategy = strategy  def do_something(self):  self.strategy.execute()//在客户端中创建上下文对象并注入具体策略对象
context = Context(ConcreteStrategyA())  
context.do_something()  # 输出:执行策略A  
context.set_strategy(ConcreteStrategyB())  
context.do_something()  # 输出:执行策略B

六、go策略模式

以下是一个示例,展示了如何在go中实现策略模式:

//定义策略接口
type Strategy interface {  Execute()  
}
//创建具体策略类
type ConcreteStrategyA struct{}  func (s *ConcreteStrategyA) Execute() {  fmt.Println("执行策略A")  
}  type ConcreteStrategyB struct{}  func (s *ConcreteStrategyB) Execute() {  fmt.Println("执行策略B")  
}
//创建上下文类
type Context struct {  strategy Strategy  
}  func (c *Context) SetStrategy(strategy Strategy) {  c.strategy = strategy  
}  func (c *Context) DoSomething() {  c.strategy.Execute()  
}
//在客户端中创建上下文对象并注入具体策略对象
func main() {  context := &Context{}  context.SetStrategy(&ConcreteStrategyA{})  context.DoSomething()  // 输出:执行策略A  context.SetStrategy(&ConcreteStrategyB{})  context.DoSomething()  // 输出:执行策略B  
}

七、PHP策略模式

以下是一个示例,展示了如何在PHP中实现策略模式:

//定义策略接口
interface Strategy {  public function execute();  
}
//创建具体策略类
class ConcreteStrategyA implements Strategy {  public function execute() {  echo "执行策略A";  }  
}  class ConcreteStrategyB implements Strategy {  public function execute() {  echo "执行策略B";  }  
}
//创建上下文类
class Context {  private $strategy;  public function __construct(Strategy $strategy) {  $this->strategy = $strategy;  }  public function setStrategy(Strategy $strategy) {  $this->strategy = $strategy;  }  public function doSomething() {  $this->strategy->execute();  }  
}
//在客户端中创建上下文对象并注入具体策略对象
$context = new Context(new ConcreteStrategyA());  
$context->doSomething();  // 输出:执行策略A  
$context->setStrategy(new ConcreteStrategyB());  
$context->doSomething();  // 输出:执行策略B

通过以上步骤,我们实现了策略模式,使得算法可以独立于使用它的客户端,并且可以在不修改原有系统的基础上选择算法或行为。这种设计模式使得程序更加灵活和可维护。策略模式体现了开闭原则和里氏替换原则,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态地切换不同的策略实现以进行替换。

《完结》

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

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

相关文章

同为科技(TOWE)机架PDU产品在IDC数据中心机房建设中的应用

当今社会互联网发展迅速&#xff0c; 随着带宽需求的提升&#xff0c; 网络的保密性、安全性的要求就越来越迫切。PDU(Power Distribution Unit) 是 PDU具备电源分配和管理功能的电源分配管理器。PDU电源插座是多有设备运行的第一道也是最为密切的部件&#xff0c; PDU的好坏直…

【漏洞复现】panalog日志审计系统任意用户创建漏洞和后台命令执行

漏洞描述 panalog为北京派网软件有限公司,一款流量分析,日志分析管理的一款软件。存在任意用户创建漏洞和后台命令执行漏洞,可先通过任意用户创建,然后进行后台命令执行,获取服务器权限。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公…

Linux下的IMX6ULL——环境搭建与软件安装(一)

前言&#xff1a; 从今天开始我们就要用到IMX6ULL这块开发板进行linux的学习了&#xff0c;对于初学者&#xff0c;下载好资料、搭建好开发环境后&#xff0c;按照下面顺序学习即可&#xff1a; 先应用&#xff0c;再驱动&#xff0c;最后做项目。应用、驱动、项目这三个慢慢走…

【safetensor】介绍和基础代码

Hugging Face, EleutherAI, StabilityAI 用的多 介绍 文件形式 header&#xff0c;体现其特性。如果强行将pickle或者空软连接 打开&#xff0c;会出现报错。解决详见&#xff1a;debug 连接到其他教程结构和参数 安装 with pip:Copied pip install safetensors with con…

ScrapeKit 和 Swift 编写程序

以下是一个使用 ScrapeKit 和 Swift 编写的爬虫程序&#xff0c;用于爬取 图片。同时&#xff0c;我们使用了proxy 这段代码来获取代理。 import ScrapeKit ​ class PeopleImageCrawler: NSObject, ScrapeKit.Crawler {let url: URLlet proxyUrl: URL ​init(url: URL, proxy…

竞赛 深度学习人体语义分割在弹幕防遮挡上的实现 - python

文章目录 1 前言1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人体语义分割在弹幕防遮挡上的应用 该项目较为新颖&#xff0c;适合作为竞…

如何使用Vue CLI进行预渲染

在Vue CLI中使用预渲染,你可以借助插件vue-cli-plugin-prerender-spa来实现。以下是使用Vue CLI进行预渲染的步骤: 1:安装Vue CLI:首先安装Vue CLI。如果没有安装,可以通过以下命令进行全局安装: npm install -g @vue/cli2:创建Vue项目:使用Vue CLI创建一个新的Vue项…

AQS是什么?AbstractQueuedSynchronizer之AQS原理及源码深度分析

文章目录 一、AQS概述1、什么是AQS2、技术解释3、基本原理4、AQS为什么这么重要 二、AQS数据结构1、AQS的结构2、ReentrantLock与AbstractQueuedSynchronizer3、AQS的state变量4、AQS的队列5、AQS的Node&#xff08;1&#xff09;Node的waitStatus&#xff08;2&#xff09;属性…

庆祝创造力和技术:2023年的1024程序员节

2023年的10月24日已经来临&#xff0c;这意味着我们又迎来了一年一度的程序员节。这是一个属于全球程序员社区的节日&#xff0c;一个庆祝创造力、创新和技术的时刻。无论你是一名职业程序员、技术爱好者&#xff0c;还是对编程世界感兴趣的新手&#xff0c;1024程序员节都是一…

STM32+2.9inch微雪墨水屏(电子纸)实现显示

本篇文章从硬件原理以及嵌入式编程等角度完整的介绍了墨水屏驱动过程&#xff0c;本例涉及的墨水屏为2.9inch e-Paper V2,它采用的是“微胶囊电泳显示”技术进行图像显示&#xff0c;其基本原理是悬浮在液体中的带电纳米粒子受到电场作用而产生迁移&#xff0c;从而改变显示屏各…

【C++入门到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入门 ]

阅读导航 前言一、unordered系列容器二、unordered_map1. unordered_map简介⭕函数特点 2. unordered_map接口- 构造函数- unordered_map的容量- unordered_map的迭代器- unordered_map的元素访问- unordered_map的修改操作- unordered_map的桶操作 三、unordered_set1. unorde…

react中JSX基础与useState的基本使用 + 评论显示删除需求案例

参考视频&#xff1a;https://www.bilibili.com/video/BV1ZB4y1Z7o8/?p3&spm_id_frompageDriver&vd_source5c584bd3b474d579d0bbbffdf0437c70 如果没有安装create-react-app需要先全局安装 命令&#xff1a;npm i -g create-react-app1.快速搭建开发环境 create-re…

动态天气预报:Living Weather HD for Mac

Living Weather HD能够为Mac用户提供及时、准确、个性化的天气信息&#xff0c;并提供了丰富的定制选项&#xff0c;使用户能够更加方便地查看天气状况。 具有以下特点&#xff1a; 显示世界各地的准确天气预报和当地时间。自动探测出用户所在的首个地点&#xff0c;并通过搜…

CUDA学习笔记(八)Branch Divergence and Unrolling Loop

本篇博文转载于https://www.cnblogs.com/1024incn/tag/CUDA/&#xff0c;仅用于学习。 Avoiding Branch Divergence 有时&#xff0c;控制流依赖于thread索引。同一个warp中&#xff0c;一个条件分支可能导致很差的性能。通过重新组织数据获取模式可以减少或避免warp diverge…

HarmonyOS开发:Log工具类源码分析

前言 一转眼就十月中旬了&#xff0c;国庆的劲真大&#xff0c;到现在还未缓过来&#xff0c;以至于要更新的文章迟迟未发布&#xff0c;大家可以看到&#xff0c;最近一段时间的文章&#xff0c;都是关于HarmonyOS相关的&#xff0c;两个原因吧&#xff0c;一是我司有这样的任…

解决AndroidStudio Gradle只有testDebugUnitTest

问题复现&#xff1a; 问题解决&#xff1a; 1:点击Task list not built... 2:取消勾选Configure all Gradle tasks during Gradle Sync... 大功告成&#xff0c;现在去看看Gradle&#xff0c;屏蔽的都显示出来了。

深度学习 | Pytorch深度学习实践 (Chapter 1~9)

一、overview 基于pytorch的深度学习的四个步骤基本如下&#xff1a; 二、线性模型 - Linear Model 基本概念 数据集分为测试集和训练集&#xff08;训练集、开发集&#xff09;训练集&#xff08;x&#xff0c;y&#xff09;测试集只给&#xff08;x&#xff09;过拟合&#…

解读 | 快速精确的体素GICP三维点云配准算法

原创 | 文 BFT机器人 01 摘要 本文提出了体素化广义迭代最近点&#xff08;VGICP&#xff09;算法&#xff0c;用于快速准确的三维点云配准。所提出的方法通过体素化扩展了广义迭代最近点&#xff08;GICP&#xff09;方法&#xff0c;以避免昂贵的最近邻搜索&#xff0c;同时…

Microsoft Edge浏览器中使用免费的ChatGPT

一、双击打开浏览器 找到&#xff1a;扩展&#xff0c;打开 二、打开Microsoft Edge加载项 三、Move tab新标签 获取免费ChatGPT 四、启用Move tab。启用ChatGPT。 扩展 管理扩展 启用 五、新建标签页&#xff0c;使用GPT 六、使用举例 提问 GPT回复

酷开科技 | 酷开系统,为居家生活打开更精彩的窗口

电视在我们的日常生活中扮演着重要的角色。虽然&#xff0c;作为客厅C位的扛把子——电视的娱乐作用深入人心&#xff0c;但是&#xff0c;它的涵义和影响力却因我们每个人的具体生活环境而存在着种种差异&#xff0c;而我们的生活环境又受到我们所处的社会及文化环境的影响。 …