• 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*/
    

      

  • 相关阅读:
    从mysql中dump数据到本地
    浮点数为何不能进行相等性比较
    Flume安装
    Java 一致性Hash算法的学习
    zookeeper 四字命令的使用
    Mac Eclipse安装lombok
    Linux Tomcat8 启动堆内存溢出
    Netty5+Jboss(Marshalling)完成对象序列化传输
    Elasticsearch基础
    Elasticsearch设置最大返回条数
  • 原文地址:https://www.cnblogs.com/double-W/p/12808908.html
Copyright © 2020-2023  润新知