当前位置:   article > 正文

golang设计模式——策略模式_golang 策略模式

golang 策略模式

策略模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T8FSW1Su-1660572483018)(C:/Users/86158/AppData/Roaming/Typora/typora-user-images/image-20220815114229835.png)]

策略模式核心在于利用多态性,这是目前主流的面向对象语言都支持的功能。

策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

UML

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eTd6UJnE-1660572483020)(C:/Users/86158/AppData/Roaming/Typora/typora-user-images/image-20220815214739407.png)]

分析

单看策略模式,主要利用多态性。但策略模式往往不单独使用,它会和工厂模式配合使用。此时策略模式便可解耦策略的定义、创建、使用。

策略模式加工厂模式,能够达到去除if-else和switch的效果,主要靠工厂模式加持,借助于“查表法”找到指定策略进行使用。

应用场景

策略模式的应用场景还是蛮广泛的,处理同一类问题如果有多种算法,就可以使用策略模式。如根据不同活动计算优惠价格、根据商品不同类型计算税率等。

最近有一个实际业务场景可以使用策略模式,计算跨境商品税费。

跨境商品的税费和两方面有关,一是商品是否含税,二是商品类型,不同类型对应税率不一样,如常规商品和酒类商品税率不一样、税的计算方式也不一样。

所以只要知道商品是否含税、商品类型就能找到对应的计算方案。如果我们使用if-else来写,会不优雅,因为商品类型比较多,而且计算逻辑也相对复杂,所以我们可以利用查表法进行优化。

税费计算接口被交易侧调用,交易调用的时候会传商品是否含税,商品类型由项目组自行维护。那我们来看一下具体实现。

代码实现

package main

import "fmt"

const (
   Common = "COMMON"
   Win    = "WIN"
)

/**
 * @Description: 根据hscode获取商品类型
 * @param hscode
 * @return string
 */
func getProductType(hscode string) string {
   if hscode == "11" {
      return Common
   } else {
      return Win
   }
}

/**
 * @Description: 税费计算函数,金额都为分
 * @param price
 * @param qty
 * @return taxPrice
 */
type TaxComputeFunc func(price int64, qty int64) (taxPrice int64)

/**
 * @Description: 税费计算策略存储处
   0为不含税 1为含税
*/
var TaxComputeFuncMap = map[int]map[string]TaxComputeFunc{
   0: map[string]TaxComputeFunc{
      Common: common,
      Win:    win,
   },
   1: map[string]TaxComputeFunc{
      Common: common,
      Win:    win,
   },
}

/**
 * @Description: 计算普通商品税费
 * @param price
 * @param qty
 * @return taxPrice
 */
func common(price int64, qty int64) (taxPrice int64) {
   radio := 0.1
   fmt.Println("计算普通商品税费")
   return int64(float64(price*qty) * radio)
}

/**
 * @Description: 计算酒类税费
 * @param price
 * @param qty
 * @return taxPrice
 */
func win(price int64, qty int64) (taxPrice int64) {
   radio := 0.2
   fmt.Println("计算普酒类税费")
   return int64(float64(price*qty) * radio)
}

/**
 * @Description: 计算税费
 * @param withTax
 * @param productType
 * @param price
 * @param qty
 */
func ComputeTaxPrice(withTax int, productType string, price int64, qty int64) {
   if taxFunc, ok := TaxComputeFuncMap[withTax][productType]; ok {
      taxPrice := taxFunc(price, qty)
      fmt.Println("税费为", taxPrice)
   } else {
      fmt.Println("输入有误,无法计算")
   }
}

func main() {
   //获取商品是否含税、商品价格、商品数量、商品类型
   withTax := 0
   var price, qty int64 = 10000, 3
   productType := getProductType("11")
   //计算税费
   ComputeTaxPrice(withTax, productType, price, qty)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

输出:

➜ myproject go run main.go

计算普通商品税费

税费为 3000

这么写有哪些好处呢?首先代码很精简,没有一堆判断;其次无论是增加策略还是修改策略,都不会影响主框架,即main\ComputeTaxPrice,只需在TaxComputeFuncMap添加新的策略即可,很好的做到了对扩展开放,虽然对TaxComputeFuncMap有一定更改,但变动不大,能够接受。

实例

来个

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/708464
推荐阅读
相关标签