什么是策略模式?
定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。
实现
// 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
优点
- 算法可以自由切换;
- 避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护);
- 扩展性良好,增加一个策略只需实现接口即可。
缺点
-
策略类数量会增多,每个策略都是一个类,复用的可能性很小;
-
所有的策略类都需要对外暴露。
使用场景
- 多个类只有算法或行为上稍有不同的场景;
- 算法需要自由切换的场景;
- 需要屏蔽算法规则的场景。
注意
- 如果一个系统的策略多于四个,就需要考虑使用混合模式来解决策略类膨胀的问题。
网友评论