策略设计模式详解c/java/js/go/python/ts不同语言实现

刀法如飞-专注算法与设计模式 刀法如飞-专注算法与设计模式     2023-04-28     564

关键词:

简介

策略模式(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

行为型设计模式-策略模式详解(代码片段)

基本介绍策略模式(StrategyPattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,是一种对象行为型模式。模式结构Context(环境角色):持有抽象策略角色的... 查看详情

android设计模式之策略模式详解

策略模式一个功能的效果,有不同的算法与策略,根据不同的选择选择不同的结果。简单来说,只要你写过程序就用过策略模式,不要说没用过,难道if-else(switch)没用过吗…..if-else在其实就是一个策略模式的体现,根据不同的... 查看详情

行为型设计模式-策略模式详解(代码片段)

基本介绍策略模式(StrategyPattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,是一种对象行为型模式。模式结构Context(环境角色):持有抽象策略角色的... 查看详情

架构师内功心法,属于游戏设计模式的策略模式详解(代码片段)

一、策略模式的应用场景策略模式(StrategyPattern)是指定义了算法家族、分别封装起来,让它们之间可以相互替换,此模式让算法的变化不会影响到使用算法的用户。1.1应用场景假如系统中有很多类,而他们的区别仅仅在于他们... 查看详情

设计模式之策略模式(strategy)详解及代码示例(代码片段)

一、策略模式的定义  策略(Strategy)模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把... 查看详情

策略设计模式详解c/java/js/go/python/ts不同语言实现

简介策略模式(StrategyPattern)属于行为型设计模式。将每一个算法封装到具有共同接口的独立类中,根据需要来绑定策略,使得具体实现和策略解耦。当你想使用对象中各种不同的算法变体,使用if...else所带来的复杂和难以维护... 查看详情

经典案例python详解设计模式:策略模式(代码片段)

完成一项任务往往有多种方式,我们将其称之为策略。比如,超市做活动,如果你的购物积分满1000,就可以按兑换现金抵用券10元,如果购买同一商品满10件,就可以打9折,如果如果购买的金额超过500,就可以享受满减50元的优... 查看详情

设计模式之策略模式与责任链模式详解和应用(代码片段)

目录1.策略模式1.1目标1.2.内容定位1.3.定义1.4.应用场景1.5.促销优惠业务场景1.6用策略模式实现选择支付方式的业务场景1.7策略模式在框架源码中的体现1.8策略模式的优缺点2责任链模式2.1责任链楼式的应用场景2.2利用责任链模式... 查看详情

详解设计模式之策略模式(代码片段)

在讲策略模式之前,我们先看一个日常生活中的小例子:现实生活中我们到商场买东西的时候,卖场往往根据不同的客户制定不同的报价策略,比如针对新客户不打折扣,针对老客户打9折,针对VIP客户打8... 查看详情

selinux系列(十六)—三种策略模式详解targetedmls和minimum

对于SELinux来说,所选择的策略类型直接决定了使用哪种策略规则来执行主体(进程)可以访问的目标(文件或目录资源)。不仅如此,策略类型还决定需要哪些特定的安全上下文属性。通过策略类型,读者可以更精确地了解SELin... 查看详情

设计模式——策略模式

  策略模式是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。最典型的就是客户打折算法的设计,不同等级的用户打折的力度也不一样,所以... 查看详情

详解gaussdbbufferpool缓存策略,这次彻底懂了!

摘要:华为云GaussDB(formysql)是华为云自主研发的最新一代云原生数据库,采用计算存储分离、日志即数据的架构设计。具备极致可靠、极致性价比、多为扩展、完全可信等诸多特性。一、GaussDB(formysql)简介华为云GaussDB(formy... 查看详情

软考-01考试范围及知识点

...考点浅析架构科目2考点详解系统规划、软件架构设计、设计模式、系统设计、系统建模、分布式系统设计、嵌入式系统设计、系统的可靠性分析与设计、系统的安全性和保密性设计。架构科目3考点详解系统建模、软件架构设计... 查看详情

软考-01考试范围及知识点

...考点浅析架构科目2考点详解系统规划、软件架构设计、设计模式、系统设计、系统建模、分布式系统设计、嵌入式系统设计、系统的可靠性分析与设计、系统的安全性和保密性设计。架构科目3考点详解系统建模、软件架构设计... 查看详情

单例模式详解

...用场景、常见的单例模式写法、保证线程安全的单例模式策略、反射暴力攻击单例解决方案及原理分析、序列化破坏单例的原理及解决方案。一、单例模式的应用场景单例模式(SingletonPattern)是指确保一个类在任何情况... 查看详情

单例模式详解

...用场景、常见的单例模式写法、保证线程安全的单例模式策略、反射暴力攻击单例解决方案及原理分析、序列化破坏单例的原理及解决方案。一、单例模式的应用场景单例模式(SingletonPattern)是指确保一个类在任何情况... 查看详情

十二种常见设计模式代码详解

零:设计模式分类设计模式有创建型模式、结构型模式与行为型模式创建型:单例模式、工厂模式(简单工厂,工厂方法,抽象工厂)结构型:适配器模式、门面模式、装饰器模式、注册树模式、代理... 查看详情

线程池拒绝策略详解(代码片段)

...录1.前言2.ThreadPoolExecutor创建线程方式3.ThreadPoolExecutor拒绝策略测试3.1.AbortPolicy3.2.CallerRunsPolicy3.3.DiscardPolicy3.4.DiscardOldestPolicy3.5.自定义拒绝策略4.第三方实现的拒绝策略4.1.dubbo中的线程拒绝策略4.2.Netty中的线程池拒绝策略4.3.act 查看详情