Go设计模式(18)-观察者模式

简介: 终于写完了创建型和结构型设计模式(共12个),现在开始写行为型设计模式(共11个)。观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子。

终于写完了创建型和结构型设计模式(共12个),现在开始写行为型设计模式(共11个)。观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子。

UML类图位置:https://www.processon.com/view/link/60d29bf3e401fd49502afd25

本文代码链接为:https://github.com/shidawuhen/asap/blob/master/controller/design/18observer.go

1.定义

1.1观察者模式

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

UML:

图片

1.2分析

观察者模式算是比较通用的设计模式了,思路也比较清晰。Subject里有Observer集合,当Subject有更新时,通知各个Observer。Subject为了管理Observer,自身设置了增加、删除功能。

当Subject有更新,通知Observer时,有很多细节值得讨论。

第一个问题是使用同步阻塞还是异步非阻塞

  • 同步阻塞是最经典的实现方式,主要是为了代码解耦;
  • 异步非阻塞除了能实现代码解耦之外,还能提高代码的执行效率;

第二个问题是如何保证所有Observer都通知成功。

  • 方案一是利用消息队列ACK的能力,Observer订阅消息队列。Subject只需要确保信息通知给消息队列即可。
  • 方案二是Subject将失败的通知记录,方便后面进行重试。
  • 方案三是定义好规范,例如只对网络失败这种错误进行记录,业务失败类型不管理,由业务自行保证成功。

第三个问题是不同进程/系统如何进行通知。

  • 进程间的观察者模式解耦更加彻底,一般是基于消息队列来实现,用来实现不同进程间的被观察者和观察者之间的交互。

2.使用场景

观察者模式的使用场景还是很多的,它和享元模式一样,更多体现的是一种设计理念。

记得前些日子遇到一个场景,正好使用的是观察者模式。商家购买服务的订单,有多个状态,如交易成功、交易取消、开始履约等。业务场景只关注交易成功、交易取消和开始履约。如果不使用观察者模式,可以用if-else解决这个问题。但各个状态的处理逻辑比较复杂,而且状态有可能存在乱序的情况,导致要处理的case更多了。这时候用观察者模式就很合适,订单状态变更为Subject,具体处理逻辑为Observer,状态变更时,通知所有处理逻辑,谁合适处理便由谁处理。不但隔离性变好,扩展性也增强了。

3.代码实现

package main

import "fmt"

type PurchaseOperFunc func(status string, data string) (res bool, err error)

/**
 * @Author: Jason Pang
 * @Description: 注册的观察者
 */
var PurchaseOperFuncArr = []PurchaseOperFunc{
   create,
   isDeleted,
   apply,
}

/**
 * @Author: Jason Pang
 * @Description: 用于创建的观察者
 * @param status
 * @param data
 * @return res
 * @return err
 */
func create(status string, data string) (res bool, err error) {
   if status == "create" {
      fmt.Println("开始创建")
      return true, nil
   }
   return true, nil
}

/**
 * @Author: Jason Pang
 * @Description: 用于删除的观察者
 * @param status
 * @param data
 * @return res
 * @return err
 */
func isDeleted(status string, data string) (res bool, err error) {
   if status == "delete" {
      fmt.Println("开始删除")
      return true, nil
   }
   return true, nil
}

/**
 * @Author: Jason Pang
 * @Description: 用于履约的观察者
 * @param status
 * @param data
 * @return res
 * @return err
 */
func apply(status string, data string) (res bool, err error) {
   if status == "apply" {
      fmt.Println("开始履约")
      return true, nil
   }
   return true, nil
}

func main() {
   status := "create"
   data := "订单数据"
   //有状态更新时,通知所有观察者
   for _, oper := range PurchaseOperFuncArr {
      res, err := oper(status, data)
      if err != nil {
         fmt.Println("操作失败")
         break
      }
      if res == false {
         fmt.Println("处理失败")
         break
      }
   }
}

输出:

➜ myproject go run main.go

开始创建

这个代码是个简单版,但整体逻辑是一样的。这种写法的好处有如下几个:

  1. 如果要处理新的状态,则实现后再PurchaseOperFuncArr添加即可,改动不大
  2. 根据具体业务来说,只能有一个逻辑是真正负责执行的,所以有一个错误就报错,然后重试即可。不过具体逻辑需要做好幂等

总结

实际上,设计模式要干的事情就是解耦。创建型模式是将创建和使用代码解耦,结构型模式是将不同功能代码解耦,行为型模式是将不同的行为代码解耦,具体到观察者模式,它是将观察者和被观察者代码解耦。

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

相关文章
|
2月前
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
58 3
|
26天前
|
设计模式 存储 供应链
前端必须掌握的设计模式——观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种订阅机制。它包含两个角色:**观察者**(订阅消息、接收通知并执行操作)和**被观察者**(维护观察者列表、发送通知)。两者通过一对多的关系实现解耦,当被观察者状态改变时,会通知所有订阅的观察者。例如,商店老板作为被观察者,记录客户的需求并在商品到货时通知他们。前端应用中,如DOM事件注册、MutationObserver等也体现了这一模式。
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
3月前
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
60 0
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
48 1
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
32 3
|
3月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
39 9
|
3月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
44 2
|
3月前
|
设计模式 监控 UED
设计模式之观察者模式
【10月更文挑战第12天】 观察者模式是一种行为型设计模式,定义了一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动更新。主要由主题(被观察者)和观察者组成,实现对象间的松耦合,广泛应用于用户界面、事件驱动系统和数据监控等领域。

热门文章

最新文章

  • 1
    设计模式转型:从传统同步到Python协程异步编程的实践与思考
    64
  • 2
    C++一分钟之-设计模式:工厂模式与抽象工厂
    54
  • 3
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    60
  • 4
    C++一分钟之-C++中的设计模式:单例模式
    79
  • 5
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    47
  • 6
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    80
  • 7
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    70
  • 8
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    54
  • 9
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    63
  • 10
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    137