策略模式
是一种行为型的设计模式,该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户,或者认为把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
结构
- 1.抽象策略(Strategy)类。定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
- 2.具体策略(Concrete Strategy)类。实现了抽象策略定义的接口,提供具体的算法实现。
- 3.环境(Context)类。持有一个策略类的引用,最终给客户端调用。
优缺点
- 优点
1.避免使用多重判断。多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如 if...else 语句、switch...case 语句。
2.提供可重用的算法族,通过继承在父类实现。策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
3.策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
4.支持开闭模式,不修改源码下,灵活增加新算法。
5.算法的使用和实现分类,解耦。算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
- 缺点
1.客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
2.策略模式造成很多的策略类,增加维护难度。
适用场景
- 1.一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
- 2.类中定义多种行为,行为引用通过条件判断,可转为策略模式。
- 3.系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
- 4.系统要求使用算法的客户不应该知道其操作的数据,使用策略模式来隐藏与算法相关的数据结构。
- 5.多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。
代码实现
package main
import "fmt"
// 1.abstract strategy
type iCash interface {
acceptCash(price float64) float64
}
// 2.concrete strategy
// 2.1 normal
type cashNormal struct {
}
func (r *cashNormal) acceptCash(price float64) float64 {
if price < 0 {
return -1
}
return price
}
// 2.2 full deduction
type cashFullDeduction struct {
amount float64 // 满减要求达到多少金额
offAmount float64 // 满减的金额
}
func (r *cashFullDeduction) acceptCash(price float64) float64 {
if price < 0 || r.amount < 0 || r.offAmount < 0 {
return -1
}
if price >= r.amount {
return price - float64(int(price/r.amount))*r.offAmount
}
return price
}
// 2.3 discount
type cashDiscount struct {
discount float64
}
func (r *cashDiscount) acceptCash(price float64) float64 {
if price < 0 || r.discount < 0 {
return -1
}
if r.discount >= 1 {
return price
}
return price * r.discount
}
// 3.context
type cashCtx struct {
c iCash
}
type discountType int
const (
normalTyp discountType = 0 + iota
fullDeductionTyp
discountTyp
)
// as config
const (
AMOUNT float64 = 500
OFFAMOUNT float64 = 80
DISCOUNT float64 = 0.95
)
func NewCashCtx(typ discountType) *cashCtx {
ctx := &cashCtx{}
switch typ {
case normalTyp:
ctx.c = &cashNormal{}
case fullDeductionTyp:
ctx.c = &cashFullDeduction{AMOUNT, OFFAMOUNT}
case discountTyp:
ctx.c = &cashDiscount{DISCOUNT}
default:
panic("calculate error.")
}
return ctx
}
func (r *cashCtx) getResult(price float64) float64 {
return r.c.acceptCash(price)
}
// client
func main() {
var total float64
cash1 := NewCashCtx(normalTyp)
total += cash1.getResult(100)
cash2 := NewCashCtx(fullDeductionTyp)
total += cash2.getResult(600)
cash3 := NewCashCtx(discountTyp)
total += cash3.getResult(430)
fmt.Println("total cost:", total) // total cost: 1028.5
}
参考文章:
标签:total,return,策略,float64,price,优缺点,golang,算法,设计模式 From: https://www.cnblogs.com/davis12/p/17469986.html