首页 > 编程语言 >【策略设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

【策略设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

时间:2023-04-28 09:37:23浏览次数:47  
标签:Run 策略 Python Context Java 设计模式 public StrategyB StrategyC

简介

策略模式(Strategy Pattern)属于行为型设计模式。将每一个算法封装到具有共同接口的独立类中,根据需要来绑定策略,使得具体实现和策略解耦。

当你想使用对象中各种不同的算法变体,使用if...else 所带来的复杂和难以维护,可使用策略模式。或者当有许多相同类,它们仅在执行某些行为时略有不同,可使用策略模式。

作用

  1. 策略算法可以自由切换,保持策略与执行类的松耦合。
  2. 避免使用多重条件判断,不同环境角色可以组装多个策略。
  3. 扩展性良好,可以随时增删策略行为。
  4. 体现了多用组合,少用继承。

实现步骤

  1. 建立一个策略接口。
  2. 新建多个策略行为类,实现该策略接口。
  3. 建立一个抽象环境角色类,并将策略接口组合进来。是否需要抽象类可选。
  4. 建立多个环境角色类来继承该抽象类。
  5. 可以动态改变环境角色的策略行为。

 

不同语言设计模式源码下载:

https://github.com/microwind/design-pattern

UML

 

Java代码

状态基础接口

// Strategy.java 基础策略接口
public interface Strategy {
  public void run();
}

策略实现类

// StrategyA.java 策略A
public class StrategyA implements Strategy {
 
  @Override
  public void run() {
     System.out.println("StrategyA::run().");
  }
}
// StrategyB.java 策略B
public class StrategyB implements Strategy {
 
  @Override
  public void run() {
     System.out.println("StrategyB::run().");
  }
}
// StrategyC.java 策略C
public class StrategyC implements Strategy {
 
  @Override
  public void run() {
     System.out.println("StrategyC::run().");
  }
}

抽象业务类

// Context.java 抽象业务类,聚合策略对象
public abstract class Context {

  protected Strategy strategy;

  public void setStrategy(Strategy strategy) {
    this.strategy = strategy;
  }

  public void action() {
    this.strategy.run();
  }

}

具体业务类

// ContextCat.java 业务类构造器聚合了某策略
public class ContextCat extends Context {
 
  public ContextCat() {
    // 使用某个策略
    System.out.println("ContextCat::setStrategy(StrategyC).");
    this.setStrategy(new StrategyC());
  }
}
// ContextDog.java 业务类构造器聚合了某策略
public class ContextDog extends Context {
  public ContextDog() {
    // 使用某个策略
    System.out.println("ContextDog::setStrategy(StrategyB).");
    this.setStrategy(new StrategyB());
  }
}

测试调用

  /**
   * 策略模式就是根据需要给对象绑定具体策略,使得具体实现和策略可以灵活搭配。
   * 先声明某个具体Context对象,该对象已经绑定了具体策略,同时还可以更改策略。
   */

    // 实例化某个内容,策略已经绑定上
    Context contextCat = new ContextCat();
    contextCat.action();

    // 重新设置策略
    System.out.println("reset contextCat'strategy to StrategyA.");
    contextCat.setStrategy(new StrategyA());
    contextCat.action();
    
    // 实例化某个内容,策略已经绑定上
    Context contextGog = new ContextDog();
    contextGog.action();

Go代码

状态基础接口

// Strategy.go 基础策略接口
// 定义一个策略接口,注意go语言数据类型即接口
type Strategy interface {
    Run()
}

// 写在接口文件的其他全局方法
func Init() {
    fmt.Println("strategy init!")
}

策略实现类

// StrategyA.go 策略A
type StrategyA struct {
}

// 实现策略接口的对应方法
func (s *StrategyA) Run() {
    fmt.Println("StrategyA::Run")
}
// StrategyB.go 策略B
type StrategyB struct {
}

// 实现策略接口的对应方法
func (s *StrategyB) Run() {
    fmt.Println("StrategyB::Run")
}

// StrategyC.go 策略C
type StrategyC struct {
}

// 实现策略接口的对应方法
func (s *StrategyC) Run() {
    fmt.Println("StrategyC::Run")
}

抽象业务类

// Context.go 抽象业务类,聚合策略对象
type Context struct {
    strategy Strategy
}

// 设置不同strategy,方法名首字母大写
func (c *Context) SetStrategy(s Strategy) {
    c.strategy = s
}

// 执行策略接口里面的方法
func (c *Context) Run() {
    c.strategy.Run()
}

具体业务类

// ContextCat.go 业务类构造器聚合了某策略
// 定义具体执行对象,Go没有继承,用聚合来调用Context里的函数
type ContextCat struct {
    context Context
}

// 可提前绑定具体的策略
func (c *ContextCat) Init() {
    c.context.SetStrategy(&StrategyC{})
    fmt.Println("ContextCat::init. setStrategy(StrategyC)")
}

// 调用策略方法
func (c *ContextCat) Run() {
    fmt.Println("ContextCat::run")
    c.context.Run()
}

// ContextDog.go 业务类构造器聚合了某策略
type ContextDog struct {
    context Context
}

// 可提前绑定具体的策略
func (c *ContextDog) Init() {
    c.context.SetStrategy(&StrategyB{})
    fmt.Println("ContextDog::init. setStrategy(StrategyB)")
}

// 调用策略方法
func (c *ContextDog) Run() {
    fmt.Println("ContextDog::run")
    c.context.Run()
}

测试调用

func main() {
    fmt.Println("test start:")
    // 这里src.Init来自strategy.go文件
    src.Init()

    /**
     * 策略模式就是根据需要给对象绑定具体策略,使得具体实现和策略可以灵活搭配。
     * 先声明某个具体Context对象,该对象已经绑定了具体策略,同时还可以更改策略。
     */

    // 声明策略执行对象
    context := src.Context{}

    // 设置策略A
    context.SetStrategy(&src.StrategyA{})

    // 执行策略A,打印StrategyA
    context.Run()

    // 设置策略B
    context.SetStrategy(&src.StrategyB{})
    // 执行策略B,打印StrategyB
    context.Run()

    // 执行策略C,打印StrategyC
    context.SetStrategy(&src.StrategyC{})
    context.Run()

    // /*********************** 分割线 ******************************************/

    // 直接实例化具体执行对象,策略已经绑定
    contextCat := src.ContextCat{}
    contextCat.Init()
    contextCat.Run()

    // 直接实例化具体执行对象,策略已经绑定
    contextDog := src.ContextDog{}
    contextDog.Init()
    contextDog.Run()
}

更多语言版本

不同语言设计模式源码:https://github.com/microwind/design-pattern

标签:Run,策略,Python,Context,Java,设计模式,public,StrategyB,StrategyC
From: https://www.cnblogs.com/letjs/p/17360938.html

相关文章

  • 力扣 228. 汇总区间--python
    给定一个 无重复元素的 有序整数数组nums。返回恰好覆盖数组中所有数字的最小有序区间范围列表 。也就是说,nums的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于nums的数字x。列表中的每个区间范围[a,b]应该按如下格式输出:"a->b",如果......
  • JAVA面向对象程序设计_PTA题目集04-06总结分析
    前言:JAVA_BLOG_PTA题目集4-6_总结分析 题目集四:知识点:大体如预备知识,即:通过查询JavaAPI文档,了解Scanner类中nextLine()等方法、String类中split()等方法、Integer类中parseInt()等方法的用法,了解LocalDate类中of()、isAfter()、isBefore()、until()等方法的使用规则,了解Chro......
  • 使用 for 循环遍历 Python 字典
    #list切片后仍是listlist=['a','b','c','d']print(list[:2]) #['a','b']  结果为listprint(list[:1]) #['a']     结果仍为lists='hello's1=''foriins:ifi=='e......
  • js javascript js隐藏页面上有id的控件,隐藏页面上无控件包含的文字,控制页面控件属性
    1.隐藏页面上有id的控件varinput=document.getElementsByTagName("input");//获取页面所有inputfor(vari=0;i<input.length;i++){if(input.item(i).id.indexOf("txt")>=0)//判断input的id中是否包含txt字符串{......
  • 我喜欢 Python,因为它可以帮助我回答小问题
    5-10行代码可能非常有用一遍又一遍,我看到这个教训适用。只需几行Python就可以让我的生活更轻松或回答一个简单的问题。养成用代码快速回答自己的好奇心的习惯。它将使您成为更好的开发人员,并且您会在此过程中获得很多乐趣!骰子分布今天早上,我在想棋盘游戏。在这个游戏中,您掷......
  • 设计模式-工厂篇(1)
    意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod 使一个类的实例化延迟到其子类。适用性:当一个类不知道它所必须创建的对象的类的时候。当一个类希望由它的子类来指定它所创建的对象的时候。当类将创建对象的职责委托给多个帮助子类中的某一个,并且......
  • python的设计模式
    设计模式目录设计模式一、什么是设计模式二、python实现设计模式创建型模式1.单例模式2.工厂模式一、什么是设计模式软件工程中,设计模式是指软件设计问题的推荐方案。设计模式一般是描述如何组织代码和使用最佳实践来解决常见的设计问题。需要记住一点:设计模式是高层次的方案,并......
  • python逻辑运算 and、or
    and运算符xandyand两端的操作数,如果左侧已知为False的话,则不判断右侧,并以左侧操作数的值作为整体表达式的值and两端的操作数,如果左侧判断为True的话,则继续判断右侧,并以右侧操作数的值作为整体表达式的值1and2and3#31and0and3#0   直到找到0跳出,否则一直找到......
  • java方法的内存及练习
    方法的内存一、方法调用的基本内存原理:Java内存分配栈:方法运行时使用的内存方法进栈运行,运行完毕就出栈堆:newl出来的,都在堆内存中开辟了一个小空间方法区:存储可以运行的class文件本地方法栈:JVM在使用操作系统功能的时候使用和我们开发无关寄存器:给CPU使用和......
  • Python_14 接口测试报告
    一、查缺补漏 1.测试用例要复制到pycharm执行的项目中,才能显示 2.函数用下划线,类用大驼峰 3.pycharm一行显示(不换行): File->settings->Editor->General->Console中把Usesoftwrapsin取消 4.设置成unittest在File->settings->Tools->PythonIntegratedTools->Test......