mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-25 13:16:02 +03:00
finish strategy
This commit is contained in:
parent
c3719294ff
commit
d80bb36a59
@ -1,4 +1,9 @@
|
||||
# 策略模式
|
||||
|
||||
定义一系列算法,让这些算法在运行时可以互换,使得分离算法,符合开闭原则。
|
||||
策略模式是定义一系列具有相同签名的接口方法,让这些方法在运行时可以互换.
|
||||
|
||||
通俗的讲就是同一个函数、动作、行为等接口,在不同类型的对象上有不同的实现,所以,以在运行替换,这也非常符合开闭原则.
|
||||
|
||||
常用的例子是计算加减乘除,这里用一个存款的例子,大陆居民用人民币存款,香港居民用港币.
|
||||
|
||||
向银行执行存款动作时候,给出的现金钱是不同的类型,大陆居民拿出人民币,香港居民拿出港币.
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user