观察者模式

定义

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

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

适用场景

1、当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的,可使用观察者模式;

2、当应用中的一些对象必须观察其他对象时,可使用该模式。但仅能在有限时间内或特定情况下使用。

优点

1、降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。

2、目标与观察者之间建立了一套触发机制。

缺点

1、目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。

2、当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

代码实现

被观察者有信息更新的时候,通知到所有的观察者。

type Subject struct {
observers []Observer
context string
} func NewSubject() *Subject {
return &Subject{
observers: make([]Observer, 0),
}
} func (s *Subject) Attach(o Observer) {
s.observers = append(s.observers, o)
} func (s *Subject) notify() {
for _, o := range s.observers {
o.Update(s)
}
} func (s *Subject) UpdateContext(context string) {
s.context = context
s.notify()
} type Observer interface {
Update(*Subject)
} type Customer struct {
name string
} func NewCustomer(name string) *Customer {
return &Customer{
name: name,
}
} func (r *Customer) Update(s *Subject) {
fmt.Printf("%s received %s\n", r.name, s.context)
}

测试代码

func TestObserver(t *testing.T) {
subject := NewSubject()
reader1 := NewCustomer("小明")
reader2 := NewCustomer("小红")
reader3 := NewCustomer("小李")
subject.Attach(reader1)
subject.Attach(reader2)
subject.Attach(reader3) for i := 1; i <= 10; i++ {
subject.UpdateContext(fmt.Sprintf("更新了%d", i))
fmt.Println("+++++++++++++++++++++++++++++++++")
}
}

结构图

不同场景的实现方式

针对应用场景有下面四种实现方式

1、同步阻塞的实现方式;

2、异步非阻塞的实现方式;

3、进程内的实现方式;

4、跨进程的实现方式。

栗如:可以基于消息队列实现

观察模式和发布订阅模式

有的地方会讲观察者模式不是发布订阅模式

认为发布订阅模式相对于观察者模式多了一个 Broker 来协调信息的发送者和订阅者,而观察模式是直接通知观察者。

进而认为两者的藕合程度也是不同,观察者和被观察者,是松耦合的关系,发布者和订阅者,则完全不存在耦合。

不过感觉者没有明显的区别:

观察模式中有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。

被观察者直接通知到观察者这种场景就是同步阻塞的实现方式。

在被观察者和观察者之间加入一个消息对列,这种方式使得两者能够更加的解耦,这是观察者模式中异步非阻塞的实现方式。

因此观察者模式可以认为就是发布订阅模式,当然掌握其中的精髓,然后运用到我们的业务中才是最重要的,至于是或不是其实也没那么重要了。

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/观察者模式

【大话设计模式】https://book.douban.com/subject/2334288/

【极客时间】https://time.geekbang.org/column/intro/100039001

【golang-design-pattern】https://github.com/senghoo/golang-design-pattern

【Observer vs Pub-Sub pattern】https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c

【观察者模式】https://boilingfrog.github.io/2021/11/18/使用go实现观察者模式/

设计模式学习-使用go实现观察者模式的更多相关文章

  1. C#设计模式学习笔记:(16)观察者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7928521.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第四个模式--观 ...

  2. Java设计模式学习记录-观察者模式

    前言 观察者模式也是对象行为模式的一种,又叫做发表-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式. 咱们目前用的最多的就是各种MQ(Message Queue ...

  3. Java-马士兵设计模式学习笔记-总结

    <马士兵设计模式学习>学习了以下模式: 1.装饰者模式(例子:水管工,木工) 2.策略模式(例子:老师用职称比大小.学生用成绩比大小) 3.简单工厂模式(例子:VechileFactory ...

  4. Java设计模式学习资源汇总

    本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...

  5. python之路,Day24 常用设计模式学习

    python之路,Day24 常用设计模式学习   本节内容 设计模式介绍 设计模式分类 设计模式6大原则 1.设计模式介绍 设计模式(Design Patterns) --可复用面向对象软件的基础 ...

  6. 设计模式学习--复合模式(Compound Pattern)

    设计模式学习--复合模式(Compound Pattern) 概述 ——————————————————————————————————————————————————— 2013年8月4日<H ...

  7. Java设计模式学习总结

    设计模式基础学习总结 这篇总结主要是基于我之前设计模式基础系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 更多详细内容可以查看我的专栏文章:设计模式 ...

  8. Java设计模式学习记录-GoF设计模式概述

    前言 最近要开始学习设计模式了,以前是偶尔会看看设计模式的书或是在网上翻到了某种设计模式,就顺便看看,也没有仔细的学习过.前段时间看完了JVM的知识,然后就想着JVM那么费劲的东西都看完了,说明自己学 ...

  9. C#大话设计模式学习总结

    如有雷同,不胜荣欣,如转载,请注明 C#大话设计模式学习总结 一.工厂模式 面向对象的三个特性:封装,继承和多态 1.封装 Class Operate { privatedouble _numberA ...

随机推荐

  1. Django整理(四) - URL配置

    1. URL配置 一.需求 1. 需求:在浏览器访问URL地址 http://127.0.0.1:8000/users/index 时,显示hello django信息 2. 实现 i. 需要编写一个 ...

  2. C++ostringstream用法

    ostringstream用法 1.类型转换 要求包含头文件; 字符串和int之间的互相转换: int num = 100; string str = ""; std::ostri ...

  3. mybatis 配置问题查找

    mybatis配置问题记录 org.apache.ibatis.binding.BindingException: Type interface com.xx.dao.UserDao(自己项目的文件) ...

  4. 从零入门 Serverless | 在线应用的 Serverless 实践

    作者 | 唐慧芬(黛忻) 阿里云产品专家 导读:毫无疑问,Serverless 能够在效率和成本上给用户带来巨大收益.那具体到落地又应该怎么做呢?本文就给大家详细解读 Serverless 的落地实践 ...

  5. 题解 「CTSC2018暴力写挂」

    题目传送门 题目大意 给出两个大小为 \(n\) 的树,求出: \[\max\{\text{depth}(x)+\text{depth}(y)-\text{depth}(\text{LCA}(x,y) ...

  6. 2020.5.4-ICPC Pacific Northwest Regional Contest 2019

    A. Radio Prize All boring tree-shaped lands are alike, while all exciting tree-shaped lands are exci ...

  7. CompleteFuture实现简单的任务编排实践

    CompleteFuture实现简单的任务编排实践 一:前言 ​ CompleteFuture是java8 新提供的API,是对函数式编程思想的体现,提供了很多的对于函数式编程支持.不止有同步处理功能 ...

  8. 【UE4 C++】Print、Delay、ConsoleCommand

    基于UKismetSystemLibrary PrintString /** * Prints a string to the log, and optionally, to the screen * ...

  9. WPF 排版基础

    一.WPF 排版基础 WPF使用控制面板来进行排版,控制面板实际上是一种可以放入WPF界面元素的容器.当用户把界面元素放入控制面板后,WPF会自动把这些界面元素放在它认为合适的地方.WPF开发人员需要 ...

  10. Java:阻塞队列

    Java:阻塞队列 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 1. 概述 概念 队列 队列就可以想成是一个数组,从一头进入,一头出去,排队买饭 阻塞队列 B ...