【设计模式】观察者模式

简介: 【设计模式】观察者模式

1.0版本(双向耦合)


我们描述一个工作做的实际场景来说一说观察者模式,我们在公司的时候会加入很多的群,微信群、QQ群、企业微信群、钉钉群等,他们都有一些公共的功能,第一个功能是可以邀请员工加入,第二个功能是发布群公告来通知群成员。我们员工和工作群之间就形成了符合观察者模式的特点,多位员工关注(订阅)着群公告,工作群在有重要事件的时候进行信息的发布。1.jpg


WeCharGroup类

class WeCharGroup {
  members: Programmer[] = []; // 群里面的程序员列表
  notice: string; // 公告
  addMember(member: Programmer): void {
    this.members.push(member);
  }
  setNotice(notice): void {
    this.notice = notice;
  }
  getNotice(): string {
    return this.notice;
  }
  notifyAll(): void {
    this.members.forEach(v => v.update());
  }
}


Programmer类

class Programmer {
  name: string; //程序员是谁?
  swg: WeCharGroup; //程序员在哪个群?
  constructor(name: string, swg: WeCharGroup) {
    this.name = name;
    this.swg = swg;
  }
  //程序员接收新消息。
  update() {
    console.log(
      `${this.name}您有一条新的群公告,请注意接收!\n${this.swg.getNotice()}`
    );
  }
}

我们通过面向对象的编程思想构造出了WeCharGroup、Programmer两个对象,它们的功能和属性在上面的UML类图和代码中都明确的体现了,我们现在就一起来体验一下吧!


体验进行中

  1. 第一步:创建我们的工作群。
  2. 第二步:将公司的前端小张和后端小王邀请入群并让他俩及时获取最新的群公告信息。
  3. 第三步:今天就是每周的最后一天来,设置一个公告(“下班前记得把周报写完再走。”)。
  4. 第四步:发布最新公告。

上面的步骤操作完以后,我们的小张和小王就收到了记得写周报的通知,HXD们周报写完了吗?

// 第一步:公司来个人把工作群先建起来
const workGroup = new WeCharGroup();
// 通过addMember将程序员加入群组,程序员通过群组获得最新公告
workGroup.addMember(new Programmer('前端小张', workGroup));
workGroup.addMember(new Programmer('后端小王', workGroup));
// 设置群公告
workGroup.setNotice('下班前记得把周报写完再走。');
// 发布公告
workGroup.notifyAll();


2.0版本(第一次解耦)


通过看1.0版本的UML类图可以看的出来,我们的微信群看似只能邀请程序员,这怎么能行呢,测试工程师也需要看到公告呀,还有那谁也得看公告的呀。好的我们来针对这个现象进行一次改造吧,我们的需求是什么?多种员工都能在工作群发布公告后通过update来获取到最新的公告,我们需要将现有的Programmer类进行抽象封装,因为我们的员工都要对工作群进行关注,所有我们的抽象类定义为Observer。2.jpg


Observer抽象类

abstract class Observer {
  name: string; // 说要关注群公告?
  swg: WeCharGroup; //关注的哪个群公告?
  abstract update(): void; // 接收新消息。
}


Programmer类2.0

class Programmer extends Observer {
  constructor(name: string, swg: WeCharGroup) {
    super();
    this.name = name;
    this.swg = swg;
  }
  //程序员接收新消息。
  update() {
    console.log(
      `${this.name}您有一条新的群公告,请注意接收!\n${this.swg.getNotice()}`
    );
  }
}


WeCharGroup类2.0

class WeCharGroup {
  members: Observer[] = []; // 群里面的程序员列表
  ...
  addMember(member: Observer): void {
    this.members.push(member);
  }
  ...
}


TestEngineer类

class TestEngineer extends Observer {
  constructor(name: string, swg: WeCharGroup) {
    super();
    this.name = name;
    this.swg = swg;
  }
  //测试工程师接收新消息。
  update() {
    console.log(
      `${this.name}您有一条新的群公告,请注意接收!\n${this.swg.getNotice()}`
    );
  }
}


体验一下

  1. 我们在版本1.0的第二步将测试小李邀请入群吧

在我们将观察者抽象出来后不管是我们的测试小李,还是其他岗位的同事我们都可以用最小的改动来满足他们关注群公告的需求了。

// 第一步:公司来个人把工作群先建起来
const workGroup = new WeCharGroup();
// 通过addMember将程序员加入群组,程序员通过群组获得最新公告
workGroup.addMember(new Programmer('前端小张', workGroup));
workGroup.addMember(new Programmer('后端小王', workGroup));
// ++ 邀请测试小李入群
workGroup.addMember(new TestEngineer('测试小李', workGroup));
// 设置群公告
workGroup.setNotice('下班前记得把周报写完再走。');
// 发布公告
workGroup.notifyAll();


3.0版本(第二次解耦)


在2.0的时候我们支持了不同的员工可以关注工作群里面的公告,但是在实际的职场中我们除了关注公司的微信群很可能关注这公司的企业微信群对不对,或者还有DingDing群,好多的群让人眼花缭乱的,有多少HXD的群组比好友还多的🤔️?再看一下UML类图,我们现在强行的和微信群进行耦合,我们再来改造一把,免得用到的时候手足无措。我们将群组的功能进行抽象命名为Subject。3.jpgSubject

interface Subject {
  addMember(member: Observer): void;
  setNotice(notice: string): void;
  getNotice(): string;
  notifyAll(): void;
}


DingDingGroup

class DingDingGroup {
  members: Observer[] = []; // 群里面的员工列表
  notice: string; // 公告
  addMember(member: Observer): void {
    this.members.push(member);
  }
  setNotice(notice): void {
    this.notice = notice;
  }
  getNotice(): string {
    return this.notice;
  }
  notifyAll(): void {
    this.members.forEach(v => v.update());
  }
}


WeCharGroup3.0

class WeCharGroup implements Subject {
  ...
}
复制代码

Observer2.0

abstract class Observer {
  ...
  swg: Subject; //关注的哪个群公告?
  ...
}


Programmer3.0&TestEngineer3.0

class Programmer extends Observer {
  constructor(name: string, swg: Subject) {
    super();
    this.name = name;
    this.swg = swg;
  }
  ...
}
class TestEngineer extends Observer {
  constructor(name: string, swg: Subject) {
    super();
    this.name = name;
    this.swg = swg;
  }
  ...
}


最后我们在体验一把

  1. 第一步:创建一个钉钉群
  2. 第二步:邀请三位同学加入日常群
  3. 第三步:设置群公告
  4. 第四步:发布公告
// 公司新建了一个日常钉钉群
const everyday = new DingDingGroup();
everyday.addMember(new Programmer('前端小张', everyday));
everyday.addMember(new Programmer('后端小王', everyday));
everyday.addMember(new Programmer('测试小李', everyday));
// 设置群公告
everyday.setNotice('各位同事周末愉快!!!');
// 发布公告
everyday.notifyAll();


总结


  1. 观察者模式也称为发布-订阅模式。
  2. 观察者模式定义一对多的依赖关系,让多个观察者同时关注一个主题对象,并在主题对象发生变化后通知观察者尽心更新。



相关文章
|
12月前
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
156 3
|
3月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
21天前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
188 8
|
11月前
|
设计模式 存储 供应链
前端必须掌握的设计模式——观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种订阅机制。它包含两个角色:**观察者**(订阅消息、接收通知并执行操作)和**被观察者**(维护观察者列表、发送通知)。两者通过一对多的关系实现解耦,当被观察者状态改变时,会通知所有订阅的观察者。例如,商店老板作为被观察者,记录客户的需求并在商品到货时通知他们。前端应用中,如DOM事件注册、MutationObserver等也体现了这一模式。
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
6月前
|
设计模式 消息中间件 存储
【设计模式】【行为型模式】观察者模式(Observer)
一、入门 什么是观察者模式? 观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
325 9
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
174 0
|
8月前
|
设计模式 消息中间件 存储
设计模式:观察者模式
观察者模式属于行为型设计模式,用于建立对象间的一对多依赖关系。当主题(Subject)状态变化时,所有依赖的观察者(Observer)会自动收到通知并更新。
|
12月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
190 6

热门文章

最新文章