观察者模式

定义

观察者模式(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. 【LeetCode】300.最长递增子序列——暴力递归(O(n^3)),动态规划(O(n^2)),动态规划+二分法(O(nlogn))

    算法新手,刷力扣遇到这题,搞了半天终于搞懂了,来这记录一下,欢迎大家交流指点. 题目描述: 给你一个整数数组 nums ,找到其中最长严格递增子序列的长度. 子序列是由数组派生而来的序列,删除(或不删 ...

  2. Azure Devops实践(5)- 构建springboot项目打包docker镜像及容器化部署

    使用Azure Devops构建java springboot项目,创建镜像并容器化部署 1.创建一个springboot项目,我用现有的项目 目录结构如下,使用provider项目 在根目录下添加D ...

  3. Serverless 解惑——函数计算如何安装字体

    前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算准 ...

  4. Serverless 对研发效能的变革和创新

    作者 | 杨皓然(不瞋) 对企业而言,Serverless 架构有着巨大的应用潜力.随着云产品的完善,产品的集成和被集成能力的加强,软件交付流程自动化能力的提高,我们相信在 Serverless 架构 ...

  5. 题解 P6454 麻将 加强版

    题目传送门 题目大意 不想写了,直接看题面吧. 思路 被这个题搞自闭了,因为读错题目想一个非常恶心的东西想了一场考试,然后就删代码,然后就被骂了.哎. 需要注意的是:我们只能选一次雀头 于是,不难看出 ...

  6. flask 之 请求钩子

    请求钩子 什么是请求钩子? 在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要统一处理,为了让每个视图函数避免编写重复功能的代码,flask提供了统一的接口可以添加这些处理函数,即请求钩子. f ...

  7. LCP 07.传递消息

    题目 小朋友 A 在和 ta 的小伙伴们玩传信息游戏,游戏规则如下: 有 n 名玩家,所有玩家编号分别为 0 - n-1,其中小朋友 A 的编号为 0 每个玩家都有固定的若干个可传信息的其他玩家(也可 ...

  8. 第五课第四周笔记3:Multi-Head Attention多头注意力

    Multi-Head Attention多头注意力 让我们进入并了解多头注意力机制. 符号变得有点复杂,但要记住的事情基本上只是你在上一个视频中学到的自我注意机制的四个大循环. 让我们看一下每次计算自 ...

  9. 机器学习:KNN

    KNN:K-nearst neighbors 简介: k-近邻算法采用测量不同特征值之间的距离来进行分类,简而言之为:人以类聚,物以群分 KNN既可以应用于分类中,也可用于回归中:在分类的预测是,一般 ...

  10. [软工顶级理解组] Beta阶段测试报告

    在测试过程中发现了多少Bug? 测试阶段发现并已修复的bug: 尚且存在,但是难以解决或者不影响使用的bug: 计算重修课程的时候,如果重修课程的课程号和原课程号不同,则GPA计算会出现误差.但我们无 ...