2025年6月1日 16:55:38 星期日

go语言实现设计模式(一):策略模式

策略模式定义了算法家族,在调用算法家族的时候不感知算法的变化,客户也不会受到影响。

下面用《大话设计模式》中的一个实例进行改写。

例:超市中经常进行促销活动,促销活动的促销方法就是一个个策略,如“满一百减20”,“打八折”等。现在实现策略模式,用CashContext生产策略,并完成策略的调用。

首先定义所有策略的接口。

  1. package cash
  2. type cashSuper interface {
  3. AcceptMoney(money float64) float64
  4. }

定义三个子类,实现此接口

  1. package cash
  2. //普通情况,没有折扣
  3. type cashNormal struct {
  4. }
  5. func newCashNormal() cashNormal {
  6. instance := new(cashNormal)
  7. return *instance
  8. }
  9. func (c cashNormal) AcceptMoney(money float64) float64 {
  10. return money
  11. }
  12. package cash
  13. //打折,传入打折的折扣,如0.8
  14. type cashRebate struct {
  15. Rebate float64 //折扣
  16. }
  17. func newCashRebate(rebate float64) cashRebate {
  18. instance := new(cashRebate)
  19. instance.Rebate = rebate
  20. return *instance
  21. }
  22. func (c cashRebate) AcceptMoney(money float64) float64 {
  23. return money * c.Rebate
  24. }
  25. package cash
  26. //直接返利,如满100返20
  27. type cashReturn struct {
  28. MoneyCondition float64
  29. MoneyReturn float64
  30. }
  31. func newCashReturn(moneyCondition float64, moneyReturn float64) cashReturn {
  32. instance := new(cashReturn)
  33. instance.MoneyCondition = moneyCondition
  34. instance.MoneyReturn = moneyReturn
  35. return *instance
  36. }
  37. func (c cashReturn) AcceptMoney(money float64) float64 {
  38. if money >= c.MoneyCondition {
  39. moneyMinus := int(money / c.MoneyCondition)
  40. return money - float64(moneyMinus)*c.MoneyReturn
  41. }
  42. return money
  43. }

最重要的时刻来临了,定义CashContext结构,用来做策略筛选

  1. package cash
  2. type CashContext struct {
  3. Strategy cashSuper
  4. }
  5. func NewCashContext(cashType string) CashContext {
  6. c := new(CashContext)
  7. //这里事实上是简易工厂模式的变形,用来生产策略
  8. switch cashType {
  9. case "打八折":
  10. c.Strategy = newCashRebate(0.8)
  11. case "满一百返20":
  12. c.Strategy = newCashReturn(100.0, 20.0)
  13. default:
  14. c.Strategy = newCashNormal()
  15. }
  16. return *c
  17. }
  18. //在策略生产成功后,我们就可以直接调用策略的函数。
  19. func (c CashContext) GetMoney(money float64) float64 {
  20. return c.Strategy.AcceptMoney(money)
  21. }

调用测试

  1. package main
  2. import (
  3. "cash"
  4. "fmt"
  5. )
  6. func main() {
  7. money := 100.0
  8. cc := cash.NewCashContext("打八折")
  9. money = cc.GetMoney(money)
  10. fmt.Println("100打八折实际金额为", money)
  11. money = 199
  12. cc = cash.NewCashContext("满一百返20")
  13. money = cc.GetMoney(money)
  14. fmt.Println("199满一百返20实际金额为", money)
  15. money = 199
  16. cc = cash.NewCashContext("没有折扣")
  17. money = cc.GetMoney(money)
  18. fmt.Println("199没有折扣实际金额为", money)
  19. }
  20. /***************************************
  21. 输出:
  22. 100打八折实际金额为 80
  23. 199满一百返20实际金额为 179
  24. 199没有折扣实际金额为 199
  25. */

总结:策略模式解除了客户对策略的感知,所有策略,甚至cashSuper皆为私有。只需要暴露CashContext就可以生成策略。降低了耦合。

来自 大脸猫 写于 2015-10-31 22:06 -- 更新于2020-10-19 13:06 -- 1 条评论

1条评论

字体
字号


评论:

● 来自 KA6127 写于 2015-11-02 15:28 回复