模式特点:定义算法家族并且分别封装,它们之间可以相互替换而不影响客户端,客户只知道一个类就可以了。
程序实例:商场促销。
package main
import (
"fmt"
)
type CashSuper interface {
AcceptCash(price float64) float64
}
//正常
type CashNormal struct {
}
func (this *CashNormal) AcceptCash(price float64) float64 {
if price < 0 {
panic("不允许负数作为参数")
}
return price
}
type CashRebate struct {
condition float64
rebate float64
}
// 满减
func (this *CashRebate) AcceptCash(price float64) float64 {
if price < 0 || this.condition < 0 || this.rebate < 0 {
panic("不允许负数作为参数")
}
if price >= this.condition {
return price - float64(int(price/this.condition))*this.rebate
} else {
return price
}
}
type CashDiscount struct {
discount float64
}
// 折扣
func (this *CashDiscount) AcceptCash(price float64) float64 {
if price < 0 || this.discount < 0 {
panic("不允许负数作为参数")
}
if this.discount >= 1 {
panic("折扣无效")
}
return price * this.discount
}
type CashContext struct {
cs CashSuper
}
func (this *CashContext) GetResult(price float64) float64 {
return this.cs.AcceptCash(price)
}
func NewCashContext(style string) *CashContext {
context := &CashContext{}
switch style {
case "正常收费":
context.cs = &CashNormal{}
case "满300返100":
context.cs = &CashRebate{300, 100}
case "8折":
context.cs = &CashDiscount{0.8}
default:
panic("计价方式错误!")
}
return context
}
func main() {
var total float64
cash1 := NewCashContext("正常收费")
total += cash1.GetResult(1 * 10000)
cash2 := NewCashContext("满300返100")
total += cash2.GetResult(1 * 10000)
cash3 := NewCashContext("8折")
total += cash3.GetResult(1 * 10000)
fmt.Println("total:", total)
}