首页 > 其他分享 >golang实现设计模式之策略模式-优缺点,适用场景

golang实现设计模式之策略模式-优缺点,适用场景

时间:2023-06-09 18:23:25浏览次数:44  
标签:total return 策略 float64 price 优缺点 golang 算法 设计模式

策略模式是一种行为型的设计模式,该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户,或者认为把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

结构

  • 1.抽象策略(Strategy)类。定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
  • 2.具体策略(Concrete Strategy)类。实现了抽象策略定义的接口,提供具体的算法实现。
  • 3.环境(Context)类。持有一个策略类的引用,最终给客户端调用。

优缺点

  • 优点

1.避免使用多重判断。多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
2.提供可重用的算法族,通过继承在父类实现。策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
3.策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
4.支持开闭模式,不修改源码下,灵活增加新算法。
5.算法的使用和实现分类,解耦。算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

  • 缺点

1.客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
2.策略模式造成很多的策略类,增加维护难度。

适用场景

  • 1.一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
  • 2.类中定义多种行为,行为引用通过条件判断,可转为策略模式。
  • 3.系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
  • 4.系统要求使用算法的客户不应该知道其操作的数据,使用策略模式来隐藏与算法相关的数据结构。
  • 5.多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。

代码实现

package main

import "fmt"

// 1.abstract strategy
type iCash interface {
   acceptCash(price float64) float64
}

// 2.concrete strategy
// 2.1 normal
type cashNormal struct {

}

func (r *cashNormal) acceptCash(price float64) float64 {
   if price < 0 {
      return -1
   }
   return price
}

// 2.2 full deduction
type cashFullDeduction struct {
   amount float64 // 满减要求达到多少金额
   offAmount float64 // 满减的金额
}

func (r *cashFullDeduction) acceptCash(price float64) float64 {
   if price < 0 || r.amount < 0 || r.offAmount < 0 {
      return -1
   }
   if price >= r.amount {
      return price - float64(int(price/r.amount))*r.offAmount
   }
   return price
}

// 2.3 discount
type cashDiscount struct {
   discount float64
}

func (r *cashDiscount) acceptCash(price float64) float64 {
   if price < 0 || r.discount < 0 {
      return -1
   }
   if r.discount >= 1 {
      return price
   }
   return price * r.discount
}

// 3.context
type cashCtx struct {
   c iCash
}

type discountType int

const (
   normalTyp discountType = 0 + iota
   fullDeductionTyp
   discountTyp
)

// as config
const (
   AMOUNT float64 = 500
   OFFAMOUNT float64 = 80
   DISCOUNT float64 = 0.95
)

func NewCashCtx(typ discountType) *cashCtx {
   ctx := &cashCtx{}
   switch typ {
   case normalTyp:
      ctx.c = &cashNormal{}
   case fullDeductionTyp:
      ctx.c = &cashFullDeduction{AMOUNT, OFFAMOUNT}
   case discountTyp:
      ctx.c = &cashDiscount{DISCOUNT}
   default:
      panic("calculate error.")
   }

   return ctx
}

func (r *cashCtx) getResult(price float64) float64 {
   return r.c.acceptCash(price)
}

// client
func main()  {
   var total float64
   cash1 := NewCashCtx(normalTyp)
   total += cash1.getResult(100)
   cash2 := NewCashCtx(fullDeductionTyp)
   total += cash2.getResult(600)
   cash3 := NewCashCtx(discountTyp)
   total += cash3.getResult(430)

   fmt.Println("total cost:", total) // total cost: 1028.5
}

参考文章:

标签:total,return,策略,float64,price,优缺点,golang,算法,设计模式
From: https://www.cnblogs.com/davis12/p/17469986.html

相关文章

  • golang实现设计模式之适配器模式-优缺点,适用场景
    适配器模式是一种结构型设计模式,它是通过接口转换,使得原先接口不被兼容的其他类可以一起工作。类型类结构型特点:-程序耦合性高-要求程序员对组件内部结构熟悉-应用相对少些类适配器模式可以用过继承的方式来实现。对象结构型特点:可重用性较差。对象适配器允许一......
  • golang实现设计模式之观察者模式-优缺点,适用场景
    观察者模式是一种行为型模式,其定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象。观察者模式常用订阅/发布机制,即发布者持有所有订阅者,当发布者状态变更或者特定行为时,通知所有订阅者。结构1.发布者。属性及行为:属性,订阅者列表,行为,添加、删除订阅者方......
  • golang实现设计模式之模板模式-优缺点,适用场景
    模板模式是一种行为型设计模式,其定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。特点1.算法结构已确定。2.具体实现交由子类实现。结构1.抽象类(AbstractClass)。算法步骤可以被声明为抽......
  • 基于网卡地址做设备指纹的优缺点
    生成设备指纹的目的是为了能唯一地标识设备,而且这个标识在设备的生命周期内保持稳定。因此,在选择设备特征时,通常需要考虑这些特征的唯一性和稳定性。软件及配置信息一版不适合,是因为这类变化虽然不大,但万一变化后,设备指纹会变,影响使用。比如:操作系统信息:操作系统版本、安装日......
  • 4月29日邓老师设计模式面试资料 一般有用 看1
    【金三银四】设计模式篇1.谈谈你对设计模式的理解1.首先谈设计模式的作用:经验的传承,提高了软件复用的水平,最终达到提高软件开发效率设计原则简单说明单一职责一个类只负责一项职责里氏替换原则子类可以扩展父类的功能,但不能改变父类原有的功能依赖倒置原则要依......
  • 9.3 模版设计模式
    抽象类的设计应该是比类更高一层的设计。抽象类最大好处:1.对子类方法对统一管理;2.可以自身提供有一些普通方法,并且这些普通方法可以调用抽象方法(这些抽象方法必须在有子类提供实现的时候才会生效)abstractclassAction{ //定义公共行为类 publicstaticfinal......
  • Golang 配置代理
    通过 goget 命令下载各种依赖时,经常需要访问github/google等网站。配置好代理后,可以快速稳定的访问。常用的go代理goproxyhttps://goproxy.io/zh/阿里云https://mirrors.aliyun.com/goproxy/七牛云https://goproxy.cn设置go代理go1.13及以上版本可以直接用下面......
  • 性能测试-第01天-从理解到体验,最后能够对比说出Loadrunner和JMeter的优缺点
    更多功能测试以及全套学习路线图均在专栏,↑↑戳进去领取~系列文章目录......
  • 序) 设计模式参考资料
    https://sourcemaking.com/design_patternshttp://javapapers.com/design-patterns/  DesignPatternsInsoftwareengineering,a designpattern isageneralrepeatablesolutiontoacommonlyoccurringprobleminsoftwaredesign.Adesignpatternisn't......
  • Golang之Reflect包
    Golang之Reflect什么是Golang的Reflect包?Golang的Reflect包(reflect)是一个强大的内置包,它提供了在运行时进行程序反射的功能。通过使用Reflect包,我们可以在不了解类型的情况下,动态地检查变量的类型、调用函数和方法,以及修改变量的值。为什么使用Golang的Reflect包?Golang的Reflec......