Go语言设计模式(四)

2021-02-02 13:17

阅读:621

标签:大型   存储   无法   var   对象   not   setvalue   use   语言   

 

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

  

 

Go语言设计模式(四)

标签:大型   存储   无法   var   对象   not   setvalue   use   语言   

原文地址:https://www.cnblogs.com/double-W/p/12808908.html


评论


亲,登录后才可以留言!