最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之golang
中介者模式(Mediator Pattern)又叫做调解者模式或调停者模式。 用一个中介对象封装一系列对象交互, 中介者使各对象不须要显式地相互做用, 从而使其耦合松散, 并且能够独立地改变它们之间的交互, 属于行为型设计模式。 中介者模式主要适用于如下应用场景。 (1)系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。 (2)交互的公共行为,若是须要改变行为,则能够增长新的中介者类。 (摘自 谭勇德 <<设计模式就该这样学>>)
mediator_pattern_test.go设计模式
package behavioral_patterns import ( "learning/gooop/behavioral_patterns/mediator" "testing" ) func Test_MediatorPattern(t *testing.T) { // 设备注册 center := mediator.DefaultCloudCenter light := mediator.NewMockSmartLight(1) center.Register(light) fnCallAndLog := func(fn func() error) { e := fn() if e != nil { t.Log(e) } } // 建立app app := mediator.NewMockPhoneApp(mediator.DefaultCloudMediator) // 设备控制测试 fnCallAndLog(func() error { return app.LightOpen(1) }) fnCallAndLog(func() error { return app.LightSwitchMode(1, 1) }) fnCallAndLog(func() error { return app.LightSwitchMode(1, 2) }) fnCallAndLog(func() error { return app.LightClose(1) }) }
t$ go test -v mediator_pattern_test.go === RUN Test_MediatorPattern tMockSmartLight.open, id=1 tMockSmartLight.switchMode, id=1, mode=1 tMockSmartLight.switchMode, id=1, mode=2 tMockSmartLight.close, id=1 --- PASS: Test_MediatorPattern (0.00s) PASS ok command-line-arguments 0.002s
虚拟的手机app, 用于跟云中心通讯, 控制智能设备架构
package mediator import ( "errors" "fmt" ) type MockPhoneApp struct { mediator ICloudMediator } func NewMockPhoneApp(mediator ICloudMediator) *MockPhoneApp { return &MockPhoneApp{ mediator, } } func (me *MockPhoneApp) LightOpen(id int) error { return me.lightCommand(id, "light open") } func (me *MockPhoneApp) LightClose(id int) error { return me.lightCommand(id, "light close") } func (me *MockPhoneApp) LightSwitchMode(id int, mode int) error { return me.lightCommand(id, fmt.Sprintf("light switch_mode %v", mode)) } func (me *MockPhoneApp) lightCommand(id int, cmd string) error { res := me.mediator.Command(id, cmd) if res != "OK" { return errors.New(res) } return nil }
云中心面向手机app的接口app
package mediator type ICloudMediator interface { Command(id int, cmd string) string }
云中心面向智能设备的注册接口运维
package mediator type ICloudCenter interface { Register(dev ISmartDevice) }
智能设备接口oop
package mediator type ISmartDevice interface { ID() int Command(cmd string) string }
虚拟的云中心服务类, 面向手机app实现ICloudMediator接口, 面向智能设备实现ICloudCenter接口单元测试
package mediator import "sync" type tMockCloudMediator struct { mDevices map[int]ISmartDevice mRWMutex *sync.RWMutex } func newMockCloudMediator() ICloudMediator { return &tMockCloudMediator{ make(map[int]ISmartDevice), new(sync.RWMutex), } } func (me *tMockCloudMediator) Register(it ISmartDevice) { me.mRWMutex.Lock() defer me.mRWMutex.Unlock() me.mDevices[it.ID()] = it } func (me *tMockCloudMediator) Command(id int, cmd string) string { me.mRWMutex.RLock() defer me.mRWMutex.RUnlock() it,ok := me.mDevices[id] if !ok { return "device not found" } return it.Command(cmd) } var DefaultCloudMediator = newMockCloudMediator() var DefaultCloudCenter = DefaultCloudMediator.(ICloudCenter)
虚拟的智能灯设备, 实现ISmartDevice接口测试
package mediator import ( "fmt" "strconv" "strings" ) type tMockSmartLight struct { id int } func NewMockSmartLight(id int) ISmartDevice { return &tMockSmartLight{ id, } } func (me *tMockSmartLight) ID() int { return me.id } func (me *tMockSmartLight) Command(cmd string) string { if cmd == "light open" { e := me.open() if e != nil { return e.Error() } } else if cmd == "light close" { e := me.close() if e != nil { return e.Error() } } else if strings.HasPrefix(cmd, "light switch_mode") { args := strings.Split(cmd, " ") if len(args) != 3 { return "invalid switch command" } n, e := strconv.Atoi(args[2]) if e != nil { return "invalid mode number" } e = me.switchMode(n) if e != nil { return e.Error() } } else { return "unrecognized command" } return "OK" } func (me *tMockSmartLight) open() error { fmt.Printf("tMockSmartLight.open, id=%v\n", me.id) return nil } func (me *tMockSmartLight) close() error { fmt.Printf("tMockSmartLight.close, id=%v\n", me.id) return nil } func (me *tMockSmartLight) switchMode(mode int) error { fmt.Printf("tMockSmartLight.switchMode, id=%v, mode=%v\n", me.id, mode) return nil }
中介者模式的优势 (1)减小类间依赖,将多对多依赖转化成一对多,下降了类间耦合。 (2)类间各司其职,符合迪米特法则。 中介者模式的缺点 中介者模式将本来多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。 当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。 (摘自 谭勇德 <<设计模式就该这样学>>)
(end)设计