设计模式go语言实现----观察者模式Observer

1 定义

观察者模式(Observer):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个柱体对象,这个柱体对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己

UML类图:
在这里插入图片描述
观察者模式包含四个角色:

  • Subject(抽象目标):又称为主题,是被观察的对象
  • ConcreteSubject(具体目标):抽象目标的子类,通常包含有经常发生改变的数据,当它的状态发生改变时,向其各个观察者发出通知
  • Observer(抽象观察者):观察者将对观察目标的改变做出反应
  • ConcreteObserver(具体观察者):具体观察者中维持一个指向具体目标对象的引用,它用于存储具体观察者的有关状态,这些状态和具体目标的状态保持一致

我们下面以上班(在上班的时候有些同事会看股票行情,有些还会看NBA,老板则偶尔会走动,前台秘书和同事的关系比较好,等老板出来走动的时候,她会通知每位同事)为例,其UML类图如下:
在这里插入图片描述

2 go语言实现

2.1 实现Subject接口以及ConcreteSuject

type Subject interface {
	SetState(state string)
	GetState() string
	Attach(observer Observer)
	Notify()
}

type Boss struct {
	observer []Observer
	state    string
}

func (b *Boss) SetState(state string) {
	b.state = state
}

func (b Boss) GetState() string {
	return b.state
}

func (b *Boss) Attach(observer Observer) {
	b.observer = append(b.observer, observer)
}

func (b Boss) Notify() {
	for _, o := range b.observer {
		o.Update()
	}
}

type Secretary struct {
	observer []Observer
	state    string
}

func (s *Secretary) SetState(state string) {
	s.state = state
}

func (s Secretary) GetState() string {
	return s.state
}

func (s *Secretary) Attach(observer Observer) {
	s.observer = append(s.observer, observer)
}

func (s Secretary) Notify() {
	for _, o := range s.observer {
		o.Update()
	}
}

2.2 实现Observer接口以及ConcreteObserver

type Observer interface {
	Update()
}

type StockObserver struct {
	name    string
	subject Subject
}

func (so StockObserver) Update() {
	fmt.Printf("%s, %s 关闭炒股软件,开始工作\n", so.subject.GetState(), so.name)
}

type NBAObserver struct {
	name    string
	subject Subject
}

func (no NBAObserver) Update() {
	fmt.Printf("%s, %s 关闭NBA直播,开始工作\n", no.subject.GetState(), no.name)
}

2.3 使用工厂方法创建具体观察者和被观察者

func NewSubject(t string) Subject {
	switch t {
	case "boss":
		return &Boss{}
	case "secretary":
		return &Secretary{}
	default:
		return nil
	}
}

func NewObserver(t, name string, subject Subject) Observer {
	switch t {
	case "stock":
		return &StockObserver{
			name:    name,
			subject: subject,
		}
	case "nba":
		return &NBAObserver{
			name:    name,
			subject: subject,
		}
	default:
		return nil
	}
}

2.4 客户端调用

func main() {
	//创建一个通知者
	tSubject := observer.NewSubject("boss")
	//创建两个观察者,并与通知者绑定
	tObserverA := observer.NewObserver("stock", "张三", tSubject)
	tObserverB := observer.NewObserver("nba", "李四", tSubject)
	//通知者登记观察者
	tSubject.Attach(tObserverA)
	tSubject.Attach(tObserverB)
	//通知者状态改变
	tSubject.SetState("老板来了")
	//通知者开始通知观察者
	tSubject.Notify()
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值