Go设计模式(20)-策略模式

简介: 策略模式可能是很多同学学习到的第一种模式。这个模式确实适合作为开篇模式来讲,主要原因在于该模式简单、纯粹、没有太多技巧,但是很好的表达出了设计模式的理念,让读者能够直观的感受到设计模式带来的好处。

策略模式可能是很多同学学习到的第一种模式。这个模式确实适合作为开篇模式来讲,主要原因在于该模式简单、纯粹、没有太多技巧,但是很好的表达出了设计模式的理念,让读者能够直观的感受到设计模式带来的好处。

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

UML类图位置:https://www.processon.com/view/link/60d29bf3e401fd49502afd25

本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/20strategy.go

1.定义

1.1策略模式

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

UML:

图片

1.2分析

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

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

2.应用场景

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

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

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

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

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

3.代码实现

package main

import "fmt"

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

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

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

/**
 * @Author: Jason Pang
 * @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,
   },
}

/**
 * @Author: Jason Pang
 * @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)
}

/**
 * @Author: Jason Pang
 * @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)
}

/**
 * @Author: Jason Pang
 * @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)
}

输出:

➜ myproject go run main.go

计算普通商品税费

税费为 3000

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

如果大家看过我以前写的Go设计模式(18)-观察者模式,会感觉两个实现比较像。两者确实比较像,但是有一个核心地方不同,观察者模式是调用所有策略,策略模式准确找到合适的策略进行调用。

总结

策略模式很好的体现了开闭原则,也说明即使是很小的优化设计,也能给项目开发带来巨大的便利。当然,这种便利会在维护的时候得到充分体现,毕竟谁维护谁知道。

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式
  2. 招聘
  3. 思考
  4. 存储
  5. 算法系列
  6. 读书笔记
  7. 小工具
  8. 架构
  9. 网络
  10. Go语言
相关文章
|
3月前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
5天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
22 1
|
8天前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
18 2
|
22天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
43 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
32 3
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
29 2
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
64 3
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
27 3
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
30 1
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
【10月更文挑战第8天】 在软件开发的浩瀚宇宙中,设计模式如同星辰指引,照亮了代码设计与架构的航道。本文旨在深入探索PHP语境下策略模式(Strategy Pattern)的精髓,不仅剖析其内核原理,还将其融入实战演练,让理论在实践中生根发芽。策略模式,作为解决“如何优雅地封装算法族”的答案,以其独特的灵活性与扩展性,赋予PHP应用以动态变换行为的能力,而无需牵动既有的类结构。
29 2