Go语言设计模式(四)
Proxy Pattern 代理模式
The proxy pattern provides an object that controls access to another object, intercepting all calls. 代理模式提供一个对象,该对象控制对另一个对象的访问,拦截所有调用。
The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. Short idea of implementation。代理可以连接到任何东西:网络连接、内存中的大型对象、文件或其他一些昂贵或无法复制的资源。简短的实施思路:
package main import ( "fmt" "time" ) // To use proxy and to object they must implement same methods type IObject interface { ObjDo(action string) } // Object represents real objects which proxy will delegate data type Object struct { action string // Action behavior } // ProxyObject represents proxy object with intercepts actions func (obj *Object) ObjDo(action string) { fmt.Printf("I can %s", action) } // ProxyObject represents proxy object with intercepts actions type ProxyObject struct { object *Object } // ObjDo are implemented IObject and intercept action before send in real Object func (p *ProxyObject) ObjDo(action string) { if p.object == nil { p.object = new(Object) } if action == "work1" { p.object.ObjDo(action) } } func main() { proxy := ProxyObject{object:nil} proxy.ObjDo("work1") time.Sleep(1*time.Second) }
Observer Pattern 观察者模式
The observer pattern allows a type instance to "publish" events to other type instances ("observers") who wish to be updated when a particular event occurs. 观察者模式允许类型实例“发布”事件到其他类型实例(“观察者”),这些实例希望在特定事件发生时被更新。
In long-running applications—such as webservers—instances can keep a collection of observers that will receive notification of triggered events. Implementations vary, but interfaces can be used to make standard observers and notifiers。在长期运行的应用程序(如webservers)中,实例可以保存一个观察者集合,该集合将接收触发事件的通知。实现方法各不相同,但是接口可以用来创建标准的观察者和通知程序:
观察者模式包含如下角色:
1.目标(Subject): 目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。
2.具体目标(ConcreteSubject): 将有关状态存入各ConcreteObserver对象。
3. 观察者(Observer): 为那些在目标发生改变时需获得通知的对象定义一个更新接口。当它的状态发生改变时, 向它的各个观察者发出通知。
4. 具体观察者(ConcreteObserver): 维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现O b s e r v e r的更新接口以使自身状态与目标的状态保持一致。
package main import ( "container/list" "fmt" ) type Subject interface { Attach(Observer) // 注册观察者 Detach(Observer) // 释放观察者 Notify() // 通知所有注册的观察者 } type Observer interface { Update(Subject) // 观察者进行更新状态 } type ConcreteSubject struct { observers *list.List value int } func NewConcreteSubject() *ConcreteSubject { // 返回一个被观察者 s := new(ConcreteSubject) s.observers = list.New() return s } func (s *ConcreteSubject) Attach(observer Observer) { //注册观察者 s.observers.PushBack(observer) } func (s *ConcreteSubject) Detach(observer Observer) { // 释放观察者,类似于链路循环 for ob := s.observers.Front(); ob != nil; ob = ob.Next() { if ob.Value.(*Observer) == &observer { s.observers.Remove(ob) break } } } func (s *ConcreteSubject) Notify() { // 通知所有观察者 for ob := s.observers.Front(); ob != nil; ob = ob.Next() { ob.Value.(Observer).Update(s) } } func (s *ConcreteSubject) setValue(value int) { // 设置属性值 s.value = value s.Notify() } func (s *ConcreteSubject) getValue() int { return s.value // 获取值 } /** * 具体观察者 implements Observer * */ type ConcreteObserver1 struct { } func (c *ConcreteObserver1) Update(subject Subject) { println("ConcreteObserver1 value is ", subject.(*ConcreteSubject).getValue()) //监视被监视着的状态 } /** * 具体观察者 implements Observer * */ type ConcreteObserver2 struct { } func (c *ConcreteObserver2) Update(subject Subject) { fmt.Println(subject.(*ConcreteSubject)) println("ConcreteObserver2 value is ", subject.(*ConcreteSubject).getValue()) } func main() { subject := NewConcreteSubject() // 只要实现了Update函数的,满足Object接口的结构体都是可以进行注册的 observer1 := new(ConcreteObserver1) observer2 := new(ConcreteObserver2) subject.Attach(observer1) subject.Attach(observer2) subject.setValue(5) } /* &{0xc00006c360 5} ConcreteObserver1 value is 5 ConcreteObserver2 value is 5*/