github欢迎stargit
https://github.com/transienth...
命令模式是一个高内聚的模式,其定义:将一个请求封装成一个对象,从而让你使用不一样的请求把客户端参数化,对请求排除或者记录请求日志,能够提供命令的撤销和恢复功能。github
命令模式包含以下角色:golang
恰恰模式的缺点就是膨胀,若是有N个命令,问题就出来了,Command的子类会有N个。算法
package main import ( "fmt" ) /** Command: 抽象命令类 ConcreteCommand: 具体命令类 Invoker: 调用者 Receiver: 接收者 */ // receiver type TV struct { } func (p TV) Open() { fmt.Println("play...") } func (p TV) Close() { fmt.Println("stop...") } //command type Command interface { Press() } //ConcreteCommand type OpenCommand struct { tv TV } func (p OpenCommand) Press() { p.tv.Open() } //ConcreteCommand type CloseCommand struct { tv TV } func (p CloseCommand) Press() { p.tv.Close() } //invoker type Invoke struct { cmd Command } func (p *Invoke) SetCommand(cmd Command) { p.cmd = cmd } func (p *Invoke) Do() { p.cmd.Press() } type OpenCloseCommand struct { index int cmds []Command } func NewOpenCLoseCommand() *OpenCloseCommand { openCLose := &OpenCloseCommand{} openCLose.cmds = make([]Command, 2) return openCLose } func (p *OpenCloseCommand) AddCommand(cmd Command) { p.cmds[p.index] = cmd p.index++ } func (p *OpenCloseCommand) Press() { for _, item := range p.cmds { item.Press() } } func main() { //单一命令 tv := TV{} openCommand := OpenCommand{tv} invoker := Invoke{openCommand} invoker.Do() closeCommand := CloseCommand{tv} invoker.SetCommand(closeCommand) invoker.Do() //复合命令 fmt.Println("############复合命令###############") openClose := NewOpenCLoseCommand() openClose.AddCommand(openCommand) openClose.AddCommand(closeCommand) invoker.SetCommand(openClose) invoker.Do() }
中介者模式的定义为:用一个中介对象封装一系列的对象交互,中介者使各对象不须要显示地相互做用,从而使其耦合松散,并且能够独立地改变它们之间的交互。app
中介者模式化多对多依赖为一对多依赖。this
中介者模式由如下部分组成spa
减小类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减小了依赖,同时也下降了类间的耦合
中介者会膨胀得很大,并且逻辑复杂设计
package behavior import "fmt" /** Mediator: 抽象中介者 ConcreteMediator: 具体中介者 Colleague: 抽象同事类 ConcreteColleague: 具体同事类 */ //mediator 及 ConcreteMediator type UnitedNations interface { ForwardMessage(message string, country Country) } type UnitedNationsSecurityCouncil struct { USA Iraq } func (unsc UnitedNationsSecurityCouncil) ForwardMessage(message string, country Country) { switch country.(type) { case USA: unsc.Iraq.GetMessage(message) case Iraq: unsc.USA.GetMessage(message) default: fmt.Printf("The country is not a member of UNSC") } } type Country interface { SendMessage(message string) GetMessage(message string) } //Colleague以及ConcreteColleague类 type USA struct { UnitedNations } func (usa USA) SendMessage(message string) { usa.UnitedNations.ForwardMessage(message, usa) } func (usa USA) GetMessage(message string) { fmt.Printf("美国收到对方消息: %s\n", message) } type Iraq struct { UnitedNations } func (iraq Iraq) SendMessage(message string) { iraq.UnitedNations.ForwardMessage(message, iraq) } func (iraq Iraq) GetMessage(message string) { fmt.Printf("伊拉克收到对方消息: %s\n", message) }
client日志
package main import "gof23/behavior" func main() { tMediator := behavior.UnitedNationsSecurityCouncil{} usa := behavior.USA{tMediator} iraq := behavior.Iraq{tMediator} tMediator.USA = usa tMediator.Iraq = iraq usa.SendMessage("中止大规模杀伤性武器的研发,不然发动战争") iraq.SendMessage("咱们没有研发大规模杀伤性武器,也不怕战争") }
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆获得通知并被自动更新。观察者模式又叫作发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。code
观察者模式包含以下角色:
根据单一职责原则每一个类的职责是单一的,那么怎么把各个单一的职责串联成真实世界的复杂的逻辑关系呢?观察者模式能够完美地实现这里的链条形式
观察者模式须要考虑一下开发效率和运行效率问题
package observer import "fmt" //抽象观察者 type IObserver interface { Notify() //当被观察对象有理性的时候,触发观察者的Notify()方法 } //具体观察者 type Observer struct { } func (o *Observer) Notify() { fmt.Println("已经触发了观察者") }
package observer //抽象被观察者 type ISubject interface { AddObservers(observers ...IObserver) //添加观察者 NotifyObservers() //通知观察者 } //具体被观察者 type Subject struct { observers []IObserver } func (s *Subject) AddObservers(observer ...IObserver) { s.observers = append(s.observers, observer...) } func (s *Subject) NotifyObservers() { for k := range s.observers { s.observers[k].Notify() //触发观察者 } }
package main import "gof23/behavior/observer" func main() { s := new(observer.Subject) o := new(observer.Observer) s.AddObservers(o) s.NotifyObservers() }
状态模式(State Pattern) :容许一个对象在其内部状态改变时改变它的行为,对象看起来彷佛修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。
状态模式包含以下角色:
封装了转换规则。
枚举可能的状态,在枚举状态以前须要肯定状态种类。
将全部与某个状态有关的行为放到一个类中,而且能够方便地增长新的状态,只须要改变对象状态便可改变对象的行为。
容许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
可让多个环境对象共享一个状态对象,从而减小系统中对象的个数。
状态模式的使用必然会增长系统类和对象的个数。
状态模式的结构与实现都较为复杂,若是使用不当将致使程序结构和代码的混乱。
状态模式对“开闭原则”的支持并不太好,对于能够切换状态的状态模式,增长新的状态类须要修改那些负责状态转换的源代码,不然没法切换到新增状态;并且修改某个状态类的行为也需修改对应类的源代码。
package state import "fmt" //抽象状态角色 type State interface { NextState() State Update() } //具体状态角色 type GameStartState struct { } type GameRunState struct { } type GameEndState struct { } func (this *GameStartState) NextState() State { fmt.Println("Start next...") return new(GameRunState) } func (this *GameStartState) Update() { fmt.Println("Game start...") } func (this *GameRunState) NextState() State { fmt.Println("Run next...") return new(GameEndState) } func (this *GameRunState) Update() { fmt.Println("Game run...") } func (this *GameEndState) NextState() State { fmt.Println("End next...") return new(GameStartState) } func (this *GameEndState) Update() { fmt.Println("End") }
client
package main import ( "gof23/behavior/state" "time" ) //context角色 func stateMechine(state state.State, ch chan int) { for { select { case i := <-ch : if i == 1 { state.Update() state = state.NextState() } else if i == 0 { return } default: } } } func main() { st := new(state.GameStartState) ch := make(chan int) go stateMechine(st, ch) time.Sleep(time.Microsecond * 3) ch <- 1 time.Sleep(time.Microsecond * 3) ch <- 1 time.Sleep(time.Microsecond * 3) ch <- 1 time.Sleep(time.Microsecond * 3) ch <- 0 }
http://www.ituring.com.cn/art...
策略模式(Strategy Pattern):定义一系列算法,将每个算法封装起来,并让它们能够相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。
策略模式包含以下角色:
策略模式的优势
策略模式提供了对“开闭原则”的完美支持,用户能够在不修改原有系统的基础上选择算法或行为,也能够灵活地增长新的算法或行为。
策略模式提供了管理相关的算法族的办法。
策略模式提供了能够替换继承关系的办法。
使用策略模式能够避免使用多重条件转移语句。
策略模式的缺点
客户端必须知道全部的策略类,并自行决定使用哪个策略类。
策略模式将形成产生不少策略类,能够经过使用享元模式在必定程度上减小对象的数量。
package strategy //抽象策略角色 type cashStrategy interface { AcceptCash(float64) float64 } //具体策略角色 type cashNormal struct { } func (normal *cashNormal) AcceptCash(money float64) float64 { return money } type cashRebate struct { moneyRebate float64 } func (rebate *cashRebate) AcceptCash(money float64) float64 { return money * rebate.moneyRebate } type cashReturn struct { moneyCondition float64 moneyReturn float64 } func (returned *cashReturn) AcceptCash(money float64) float64 { if money >= returned.moneyCondition { return money - float64(int(money / returned.moneyCondition)) * returned.moneyReturn } else { return money } } // context角色 type CashContext struct { Stratege cashStrategy } func NewCashContext(cashType string) *CashContext { c := new(CashContext) switch cashType { case "打八折": c.Stratege = &cashRebate{0.8} case "满300返100": c.Stratege = &cashReturn{300, 100} case "正常收费": c.Stratege = &cashNormal{} } return c }
client
package main import ( "gof23/behavior/strategy" "fmt" ) func main() { var total float64 = 0 context := strategy.NewCashContext("满300返100") total += context.Stratege.AcceptCash(1 * 10000) context = strategy.NewCashContext("正常收费") total += context.Stratege.AcceptCash(1 * 10000) context = strategy.NewCashContext("打八折") total += context.Stratege.AcceptCash(1 * 10000) fmt.Println(total) }