From d80bb36a59aadff9de3a219e0cc68152f409dc21 Mon Sep 17 00:00:00 2001 From: Edward Date: Tue, 28 Apr 2020 14:43:37 +0800 Subject: [PATCH] finish strategy --- behavior/15_strategy/README.md | 7 ++- behavior/15_strategy/strategy.go | 65 +++++++++++++++------------ behavior/15_strategy/strategy_test.go | 32 ++++++++----- 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/behavior/15_strategy/README.md b/behavior/15_strategy/README.md index 3cf9802..b254364 100644 --- a/behavior/15_strategy/README.md +++ b/behavior/15_strategy/README.md @@ -1,4 +1,9 @@ # 策略模式 -定义一系列算法,让这些算法在运行时可以互换,使得分离算法,符合开闭原则。 +策略模式是定义一系列具有相同签名的接口方法,让这些方法在运行时可以互换. +通俗的讲就是同一个函数、动作、行为等接口,在不同类型的对象上有不同的实现,所以,以在运行替换,这也非常符合开闭原则. + +常用的例子是计算加减乘除,这里用一个存款的例子,大陆居民用人民币存款,香港居民用港币. + +向银行执行存款动作时候,给出的现金钱是不同的类型,大陆居民拿出人民币,香港居民拿出港币. diff --git a/behavior/15_strategy/strategy.go b/behavior/15_strategy/strategy.go index f96b50a..e1df05c 100644 --- a/behavior/15_strategy/strategy.go +++ b/behavior/15_strategy/strategy.go @@ -2,44 +2,53 @@ package strategy import "fmt" -type Payment struct { - context *PaymentContext - strategy PaymentStrategy -} +//money kind +const ( + RMB = "RMB" + HK = "HK" +) -type PaymentContext struct { - Name, CardID string +//StoreContext for Store 要包存钱的上下文信息 +type StoreContext struct { + Kind, CardID string Money int } -func NewPayment(name, cardid string, money int, strategy PaymentStrategy) *Payment { - return &Payment{ - context: &PaymentContext{ - Name: name, - CardID: cardid, - Money: money, - }, - strategy: strategy, - } +//IStore 要实现的存钱接口 +type IStore interface { + Store(*StoreContext) } -func (p *Payment) Pay() { - p.strategy.Pay(p.context) +//MainLandCitizen 大陆居民 +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 { - Pay(*PaymentContext) +//HongKongCitizen 香港居民 +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{} - -func (*Cash) Pay(ctx *PaymentContext) { - fmt.Printf("Pay $%d to %s by cash", ctx.Money, ctx.Name) +//Bank handle moneyholder +type Bank struct { + moneyHolder IStore } -type Bank struct{} - -func (*Bank) Pay(ctx *PaymentContext) { - fmt.Printf("Pay $%d to %s by bank account %s", ctx.Money, ctx.Name, ctx.CardID) - +//Recept a user +func (b *Bank) Recept(moneyHolder IStore) { + b.moneyHolder = moneyHolder + 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) } diff --git a/behavior/15_strategy/strategy_test.go b/behavior/15_strategy/strategy_test.go index de88592..fe515a1 100644 --- a/behavior/15_strategy/strategy_test.go +++ b/behavior/15_strategy/strategy_test.go @@ -1,15 +1,25 @@ package strategy -func ExamplePayByCash() { - payment := NewPayment("Ada", "", 123, &Cash{}) - payment.Pay() - // Output: - // Pay $123 to Ada by cash -} +import "testing" -func ExamplePayByBank() { - payment := NewPayment("Bob", "0002", 888, &Bank{}) - payment.Pay() - // Output: - // Pay $888 to Bob by bank account 0002 +func TestStoreMoney(t *testing.T) { + + bank := Bank{&MainLandCitizen{"Miss White"}} + ctx := &StoreContext{ + 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) }