设计模式:策略模式(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.rhkb.cn/news/167817.html

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

相关文章

AI的Prompt是什么

一.AI的Prompt的作用 在人工智能&#xff08;AI&#xff09;中&#xff0c;"Prompt"通常指的是向AI系统提供的输入或指令&#xff0c;用于引导AI进行特定的操作或生成特定的输出。例如&#xff0c;在一个对话型AI系统中&#xff0c;用户输入的问题就是一个prompt&…

使用 VS 2022 开发C#项目的tips

代码操作 删除注释或空行 参考C#【必备技能篇】Visual Studio删除所有的注释和空行 删除所有行注释&#xff1a;包括行内和行外&#xff0c;如下所示 Ctrl H 替换&#xff0c;第一行输入&#xff1a;//[^\n]*\n, 第二行输入&#xff1a;\n。替换即可。 这一步可能出现很多空…

C#上位机序列9: 批量读写+事件广播+数据类型处理

一、源码结构&#xff1a; 二、运行效果&#xff1a; 三、源码解析 1. 读取配置文件及创建变量信息&#xff08;点位名称&#xff0c;地址&#xff0c;数据类型&#xff08;bool/short/int/float/long/double&#xff09;&#xff09; 2. 异步任务处理&#xff1a;读任务&…

组态软件和人机界面与plc之间Profinet无线通讯

在实际应用中&#xff0c;车间里分布的多台PLC&#xff0c;会由一台触摸屏集中控制&#xff0c;同时用户也许要将PLC数据共享给总控的上位机软件进行数据监控。此时需要实现&#xff0c;PLC、触摸屏、上位机之间的数据实时共享功能。在有通讯需求的时候&#xff0c;如果布线的话…

正规文法、正规式、确定的有穷自动机DFA、不确定的有穷自动机NFA 的概念、区分以及等价性转换【我直接拿下!】

文章目录 正规文法正规式有穷自动机确定的有穷自动机——DFA不确定的有穷自动机——NFADFA 与 NFA 的区分 正规式转换为正规文法正规文法转换为正规式NFA 转换为 DFANFA 最小化 NFA 转换为正规式正规式转换为 NFA正规文法转换为 NFANFA 转换为正规文法 前言&#xff1a; 在学习…

每日一题 2316. 统计无向图中无法互相到达点对数(中等,图连通分量)

题目很简单&#xff0c;只要求出每个连通分量有多少个节点即可首先通过建立一个字典来表示每个节点的邻接关系遍历每个节点&#xff0c;并通过邻接关系标记在当前连通分量内的所有的点&#xff0c;这样就可以知道一个连通分量内有多少个点在这里我陷入了一个误区&#xff0c;导…

NET7下用WebSocket做简易聊天室

NET7下用WebSocket做简易聊天室 步骤&#xff1a; 建立NET7的MVC视图模型控制器项目创建websocket之间通信的JSON字符串对应的实体类一个房间用同一个Websocketwebsocket集合类&#xff0c;N个房间创建websocket中间件代码Program.cs中的核心代码&#xff0c;使用Websocket聊…

【Linux】32条指令带你玩转 Linux !

目录 1&#xff0c;whoami 2&#xff0c;who 3&#xff0c;pwd 4&#xff0c;ls 1&#xff0c;ls 2&#xff0c;ls -l 3&#xff0c;ls -a 4&#xff0c;ls -al 5&#xff0c;ls -d 6&#xff0c;ls -ld 5&#xff0c;clear 6&#xff0c;cd 1&#xff0c;cd 2&…

老胡的周刊(第112期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 LocalAI[2] &#x1f916; 免费、开源的 Ope…

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测

分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于LSTM-AdaBoost长短期记忆网络结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.分类预测 | MATLAB实现基于LSTM-Ada…

强化学习问题(7)--- Python和Pytorch,Tensorflow的版本对应

1.问题 之前下载的python3.8&#xff0c;在对应Pytorch和Tensorflow时没太在意版本&#xff0c;在运行一些代码时&#xff0c;提示Pytorch和Tensorflow版本过高&#xff0c;直接降下来&#xff0c;有时候又和Python3.8不兼容&#xff0c;所以又在虚拟环境搞一个Pyhon3.7&#x…

数字秒表verilog电子秒表跑表,代码/视频

名称&#xff1a;数字秒表verilog电子秒表跑表 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 设计电子秒表&#xff0c;秒表时间精确到0.01秒&#xff0c;可通过按键控制秒表启动、暂停、复位。 代码需要在Mini_Star开发板验证。 开发板资料&…

逐秒追加带序号输入当前时间:fgets fputs sprintf fprintf

//向某文件中逐秒追加带序号输入当前时间 #include<stdio.h> #include<stdlib.h> #include<time.h> #include<string.h> #include <unistd.h> int main(int argc, char const *argv[]) { time_t tv; // time(&tv);//法1:获取秒数 …

达索智能制造解决方案,敏捷电芯制造如何赋能企业竞争力 | 百世慧®

敏捷电芯制造赋能企业竞争力 全球电池市场正在快速扩大&#xff0c;为制造商带来巨大商机。 锂电行业的智能制造如何应用&#xff1f; 电池制造业的市场趋势是什么&#xff1f; 电池制造商面临哪些挑战&#xff1f; 特别是电池电芯制造方面&#xff0c;如何克服挑战获得竞…

python爬虫入门(一)web基础

HTTP基本要点 HTTP请求&#xff0c;由客户端向服务端发出&#xff0c;可以分为 4 部分内容&#xff1a;请求方法&#xff08;Request Method&#xff09;、请求的网址&#xff08;Request URL&#xff09;、请求头&#xff08;Request Headers&#xff09;、请求体&#xff08…

常见的状态转移矩阵和对应的运动模型

状态转移矩阵的形式取决于我们所建模的系统的动态特性。对于不同的运动模型&#xff0c;状态转移矩阵将会有所不同。以下是一些常见的状态转移矩阵和对应的运动模型&#xff1a; 恒定速度模型&#xff1a; 这是你给出的模型&#xff0c;其中物体假设以恒定速度移动。 恒定加速…

209. 长度最小的子数组

209. 长度最小的子数组 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__209长度最小的子数组_nlogn_n__209长度最小的子数组_n_1 原题链接&#xff1a; 209. 长度最小的子数组 https://leetcode.cn/problems/minimum-size-subarray-su…

ThinkPHP 3.2 常用内置函数

ThinkPHP 3.2 内置函数CDM疑问&#xff1a; D与M方法的相同点与不同点IAR 内置函数 C C方法是用于获取或修改&#xff0c;系统配置参数 语法&#xff1a; 获取&#xff1a;C&#xff08;需要获得的配置参数Name&#xff09; $value C(config_name);设置&#xff1a;C&…

css flex实现同行div根据内容高度自适应且保持一致

有情况如下&#xff1a;三个div的高度是随着内容自适应的&#xff0c;但希望每列的高度都相同&#xff0c;即&#xff0c;都与最高的相同。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewp…

在线存储系统源码 网盘网站源码 云盘系统源码

Cloudreve云盘系统源码-支持本地储存和对象储存,界面美观 云盘系统安装教程 测试环境:PHP7.1 MYSQL5.6 Apache 上传源码到根目录 安装程序: 浏览器数据 http://localhost/CloudreveInstallerlocalhost更换成你的网址 安装完毕 记住系统默认的账号密码 温馨提示:如果默认…