finish strategy

This commit is contained in:
Edward 2020-04-28 14:43:37 +08:00
parent c3719294ff
commit d80bb36a59
3 changed files with 64 additions and 40 deletions

View File

@ -1,4 +1,9 @@
# 策略模式 # 策略模式
定义一系列算法,让这些算法在运行时可以互换,使得分离算法,符合开闭原则。 策略模式是定义一系列具有相同签名的接口方法,让这些方法在运行时可以互换.
通俗的讲就是同一个函数、动作、行为等接口,在不同类型的对象上有不同的实现,所以,以在运行替换,这也非常符合开闭原则.
常用的例子是计算加减乘除,这里用一个存款的例子,大陆居民用人民币存款,香港居民用港币.
向银行执行存款动作时候,给出的现金钱是不同的类型,大陆居民拿出人民币,香港居民拿出港币.

View File

@ -2,44 +2,53 @@ package strategy
import "fmt" import "fmt"
type Payment struct { //money kind
context *PaymentContext const (
strategy PaymentStrategy RMB = "RMB"
} HK = "HK"
)
type PaymentContext struct { //StoreContext for Store 要包存钱的上下文信息
Name, CardID string type StoreContext struct {
Kind, CardID string
Money int Money int
} }
func NewPayment(name, cardid string, money int, strategy PaymentStrategy) *Payment { //IStore 要实现的存钱接口
return &Payment{ type IStore interface {
context: &PaymentContext{ Store(*StoreContext)
Name: name,
CardID: cardid,
Money: money,
},
strategy: strategy,
}
} }
func (p *Payment) Pay() { //MainLandCitizen 大陆居民
p.strategy.Pay(p.context) type MainLandCitizen struct{ Name string }
//Store Money to bank
func (m *MainLandCitizen) Store(ctx *StoreContext) {
fmt.Println("i am: ", m.Name, "i want to store: ", ctx.Money, ctx.Kind, "to: ", ctx.CardID)
} }
type PaymentStrategy interface { //HongKongCitizen 香港居民
Pay(*PaymentContext) type HongKongCitizen struct{ Name string }
//Store Money to bank
func (h *HongKongCitizen) Store(ctx *StoreContext) {
fmt.Println("i am: ", h.Name, "i want to store: ", ctx.Money, ctx.Kind, "to: ", ctx.CardID)
} }
type Cash struct{} //Bank handle moneyholder
type Bank struct {
func (*Cash) Pay(ctx *PaymentContext) { moneyHolder IStore
fmt.Printf("Pay $%d to %s by cash", ctx.Money, ctx.Name)
} }
type Bank struct{} //Recept a user
func (b *Bank) Recept(moneyHolder IStore) {
func (*Bank) Pay(ctx *PaymentContext) { b.moneyHolder = moneyHolder
fmt.Printf("Pay $%d to %s by bank account %s", ctx.Money, ctx.Name, ctx.CardID) fmt.Println("Bank: ", "Recept a New User")
}
//AccountUserMoney 动态替换的过程在这里,这里调用任何实现了Store的接口对象
//AccountUserMoney to handle User's Money
func (b *Bank) AccountUserMoney(ctx *StoreContext) {
b.moneyHolder.Store(ctx)
fmt.Println("Bank: ", "Processing Store", ctx.Money, ctx.Kind, "to: ", ctx.CardID)
} }

View File

@ -1,15 +1,25 @@
package strategy package strategy
func ExamplePayByCash() { import "testing"
payment := NewPayment("Ada", "", 123, &Cash{})
payment.Pay()
// Output:
// Pay $123 to Ada by cash
}
func ExamplePayByBank() { func TestStoreMoney(t *testing.T) {
payment := NewPayment("Bob", "0002", 888, &Bank{})
payment.Pay() bank := Bank{&MainLandCitizen{"Miss White"}}
// Output: ctx := &StoreContext{
// Pay $888 to Bob by bank account 0002 Kind: "RMB",
CardID: "12345678921",
Money: 10000,
}
bank.AccountUserMoney(ctx)
hkUser := &HongKongCitizen{"Miss Black"}
bank.Recept(hkUser)
ctx = &StoreContext{
Kind: "HK",
CardID: "987345678456",
Money: 8723,
}
bank.AccountUserMoney(ctx)
} }