【设计模式】观察者模式

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

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. 观察者模式定义一对多的依赖关系,让多个观察者同时关注一个主题对象,并在主题对象发生变化后通知观察者尽心更新。



相关文章
|
1月前
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
51 3
|
1月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
2月前
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
49 0
|
20天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
22天前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
36 1
|
1月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
28 3
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
36 9
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
35 2
|
2月前
|
设计模式 监控 UED
设计模式之观察者模式
【10月更文挑战第12天】 观察者模式是一种行为型设计模式,定义了一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动更新。主要由主题(被观察者)和观察者组成,实现对象间的松耦合,广泛应用于用户界面、事件驱动系统和数据监控等领域。
|
2月前
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
本教程详细讲解Kotlin语法,适合深入学习。对于快速掌握Kotlin,推荐“简洁”系列教程。本文特别介绍了观察者模式,包括使用Java API和Kotlin委托属性(如Delegates.observable)实现的方法,旨在帮助开发者更高效地实现和优化观察者模式的应用。
41 3