美文网首页
设计模式——策略模式

设计模式——策略模式

作者: DevilRoshan | 来源:发表于2020-11-03 23:23 被阅读0次

    什么是策略模式?

    定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。

    实现

    // CashSuper 策略类,为抽象类,抽象出收费的方法供子类实现。
    type CashSuper interface {
        AcceptCash(money float64) float64
    }
    
    // 正常收费子类
    type CashNormal struct {
    }
    
    func NewCashNormal() *CashNormal {
        return &CashNormal{}
    }
    
    func (this *CashNormal) AcceptCash(money float64) float64 {
        return money
    }
    
    // 打折收费子类
    type CashRebate struct {
        moneyRebate float64
    }
    
    func NewCashRebate(moneyRebate float64) *CashRebate {
        return &CashRebate{moneyRebate: moneyRebate}
    }
    
    func (this *CashRebate) AcceptCash(money float64) float64 {
        return money * this.moneyRebate
    }
    
    // 返利收费子类
    type CashReturn struct {
        moneyConditation float64
        moneyReturn      float64
    }
    
    func NewCashReturn(moneyConditation, moneyReturn float64) *CashReturn {
        return &CashReturn{moneyConditation: moneyConditation, moneyReturn: moneyReturn}
    }
    
    func (this *CashReturn) AcceptCash(money float64) float64 {
        result := money
        if money >= this.moneyConditation {
            result = money - math.Floor(money/this.moneyConditation)*this.moneyReturn
        }
        return result
    }
    
    // 上下文
    type CashContext struct {
        cashSuper CashSuper
    }
    
    func NewCashContext(cashSuper CashSuper) *CashContext {
        return &CashContext{cashSuper: cashSuper}
    }
    
    func (this *CashContext)GetResult(money float64) float64 {
        return this.cashSuper.AcceptCash(money)
    }
    
    func TestNewCashContext(t *testing.T) {
        var (
            in          int
            num         int
            Type        string
            price       float64
            totalPrices float64
            cashContext *CashContext
        )
        fmt.Println("选择打折方式:")
        in = 2
        switch in {
        case 1:
            cashContext = NewCashContext(NewCashNormal())
            Type += "正常收费"
        case 2:
            cashContext = NewCashContext(NewCashReturn(300, 100))
            Type += "收费满300返100"
        case 3:
            cashContext = NewCashContext(NewCashRebate(0.8))
            Type += "收费打8折"
        default:
            fmt.Println("没有选择打折方式:")
        }
        totalPrices = 0.0
        fmt.Println("请输入单价:")
        price = 11.1
        fmt.Println("请输入数量:")
        num = 30
        totalPrices = cashContext.GetResult(price * float64(num))
        fmt.Println("单价:", price)
        fmt.Println("数量:", num)
        fmt.Println("类型:", Type)
        fmt.Println("合计:", totalPrices)
    }
    // === RUN   TestNewCashContext
    // 选择打折方式:
    // 请输入单价:
    // 请输入数量:
    // 单价: 11.1
    // 数量: 30
    // 类型: 收费满300返100
    // 合计: 233
    // --- PASS: TestNewCashContext (0.00s)
    // PASS
    

    优点

    • 算法可以自由切换;
    • 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护);
    • 扩展性良好,增加一个策略只需实现接口即可。

    缺点

    • 策略类数量会增多,每个策略都是一个类,复用的可能性很小;

    • 所有的策略类都需要对外暴露。

    使用场景

    • 多个类只有算法或行为上稍有不同的场景;
    • 算法需要自由切换的场景;
    • 需要屏蔽算法规则的场景。

    注意

    • 如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略类膨胀的问题。

    相关文章

      网友评论

          本文标题:设计模式——策略模式

          本文链接:https://www.haomeiwen.com/subject/krwsvktx.html