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"
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)
}

View File

@ -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)
}