Go语言设计模式
Posted double-w
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言设计模式相关的知识,希望对你有一定的参考价值。
Proxy Pattern 代理模式
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 观察者模式
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*/
以上是关于Go语言设计模式的主要内容,如果未能解决你的问题,请参考以下文章
Go 语言也 10 岁了!这里或许有你不知道的 Go 的成长历程
一天一门编程语言设计一套Go语言中的 Stream API 接口代码实现