Lzs 2019-03-15
本文主要说一下设计模式之策略模式,后续会有更多的模式和算法以及区块链相关的,如果你是想学习go语言或者是对设计模式或者算法感兴趣亦或是区块链开发工作者,都可以关注一下。(微信公众号:Go语言之美,csdn:Go语言之美。更多go语言知识信息等)。
github(go语言算法、设计模式等持续更新):
https://github.com/rayyyes
商场打折是CRM系统中最常见的情况,商场随时会增加或者删除促销方式,而且促销方式非常多,我们需要针对各种情况做出不同的结果,例如打八折,我们就要根据实际价格计算出打八折的结果,满300返100等等。这个时候我们怎么做呢,大多数人没有接触设计模式时,都会想,只要用一个switch case语句就可以,其实这样确实可以,也能达到想要的结果,但是如果规则变得复杂了,增加和很多或者删除了很多,这样我们就很难维护了,如果有一百种促销方式,难道我们要在一百个case语句里写上各个算法吗?这样维护起来贼难受,所以我们就有了策略模式。
定义:策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
接下来我们实现一个小的商场促销模式,分别是正常收费,打八折和满300返100的撤销方法。
package main import "fmt" type CashSuper interface { AcceptCash(money float64) float64 } // 正常收费 type Normal struct { } func (this *Normal) AcceptCash(money float64) float64 { return money } // 打折 type CashRebate struct { Rebate float64 } func (this *CashRebate) SetRebate(rebate float64) { this.Rebate = rebate } func (this *CashRebate) AcceptCash(money float64) float64 { return this.Rebate * money } // 满 x 返 y type CashReturn struct { MoneyCondition float64 MoneyReturn float64 } func (this *CashReturn) SetCashReturn(moneyCondition float64, moneyReturn float64) { this.MoneyCondition = moneyCondition this.MoneyReturn = moneyReturn } func (this *CashReturn) AcceptCash(money float64) float64 { if money >= this.MoneyCondition { moneyMinus := int(money / this.MoneyCondition) return money - float64(moneyMinus)*this.MoneyReturn } return money } type CashContext struct { Strategy CashSuper } func (this *CashContext) SetCashContext(t string) { switch t { case "正常收费": normal := new(Normal) this.Strategy = normal case "打八折": r := new(CashRebate) r.SetRebate(0.8) this.Strategy = r case "满300返100": r := new(CashReturn) r.SetCashReturn(300, 100) this.Strategy = r } } func (this *CashContext) GetMoney(money float64) float64 { return this.Strategy.AcceptCash(money) } func main() { cs := new(CashContext) cs.SetCashContext("打八折") result := cs.GetMoney(100) fmt.Println("100元打八折结果:", result) cs.SetCashContext("正常收费") result = cs.GetMoney(100) fmt.Println("100元正常收费结果:", result) cs.SetCashContext("满300返100") result = cs.GetMoney(400) fmt.Println("400元满300返100结果:", result) }
这里面我们先定义了三种结构,分别是正常收费,打折和满x返y模式。每种模式都有各自独立的算法。接下来是收费上下文结构,这个是最重要的部分,也相当于一个简单工程,策略模式最常见的伙伴就是工厂模式,每种模式都有自己的用处,把每个模式的优点结合在一起才能更好的完成项目。
对于客户端,不需要具体的实现,只要将自己的需求送给CashContext就可以获得自己想要的结果。看到这里有人就会问,这和一个switch case语句有什么区别?如果我们将所有的算法都写在一起,我们很难找到对于的算法,而且对于以后的删除和增加也不好维护,并且策略模式将所有策略抽离出来,做到了低耦合。
不过话说回来,对于设计模式我们要活学活用,因为模式是死的,人是活的,需求不同,设计模式也是跟着变化的。适合项目的才是最好的。