计算机基础_设计模式

熟练使用前端常用的设计模式编写代码
如单例模式、装饰器模式、代理模式等

 

发布订阅模式和观察者模式的异同以及实际应用

一、定性区别

首先,观察者是经典软件设计模式中的一种,但发布订阅只是软件架构中的一种消息范式。所以不要再被“观察者模式和发布订阅模式xxx”这样的问题误导。

二、组成区别

 

 三、各自实现

可以看出,此时网站和用户间其实是有耦合的,也就是网站除了要维护自身功能外,还需要维护订阅者列表,并且在内容更新后完成通知工作。这样在用户和网站之间有一部分关系是维护在网站内部的。如果网站想把这部分任务抽离出来,自然便恢复至发布订阅模型,即建立单独的消息中心来管理发布者和订阅者之间的关系以及接收变化和通知消息的工作。

发布订阅的实现内部利用了观察者模式,让我们回顾一下观察者模式的核心,观察者模式由观察者和被观察者组成,其中被观察者是重点。二者的关联可以是在创建被观察者后,调用其添加观察者方法主动建立和某个观察者的关系,或是在创建观察者时即声明要观察的对象,即被观察者。其中观察者和被观察者一般为一对多关系,即一个被观察者可以被多个观察者观察。

那么分析发布订阅模型即可发现,其中订阅者发布订阅中心的关系类似观察者被观察者的关系。注意只是类似,因为虽然其中订阅者观察者都是消费的一方,期待能够即时接收到其他方的变化。

但区别在于观察者模式中的被观察者需要在每次自身改变后都绑定式地触发对观察者的通知,因为这是观察者模式这一模式所要实现的核心,也就是类似事件处理系统的机制,被观察者有义务针对自身的变化给出响应式的反馈到观察者们,这就是为什么说观察者模式是松耦合的,因为被观察者的功能不纯粹,要包含一部分观察者和自身关系的逻辑。

发布订阅与之的区别在于,因为发布者把消息通知的权限交由发布订阅中心管理,发布者只需关心自身的发布逻辑,而不会直接和其所发布内容的订阅者直接通信。订阅者也如此,其只关心向发布订阅中心注册自己想要接收通知的栏目,并实现自己在接收到通知后的逻辑,而无需关心消息来自何方,发布者是谁。因此发布者订阅者由于发布订阅中心的出现而完全解耦。

由于发布订阅中心这一中间层的出现,对于生产方和消费方的通信管理变得更加的可管理和可拓展。比如这样同样可以实现通过观察者模式实现的事件机制,即消息中心在接收到新的消息发布后即时通知到该类目下的所有订阅者,只不过此时的发布者消息中心的关系为一对一,并且消息中心订阅者一对多,消息中心只相当于发布者的一层代理。

 

四、实际应用

发布订阅模式实际应用
  • Node.js中自带的EventEmiter模块
  • Vue.js中数据响应式的实现

五、异同

  • 观察者模式里,只有两个角色 —— 观察者 + 被观察者
  • 而发布订阅模式里,却不仅仅只有发布者和订阅者两个角色,还有一个经常被我们忽略的 —— 经纪人Broker
  • 观察者和被观察者,是松耦合的关系
  • 发布者和订阅者,则完全不存在耦合
  • 观察者模式,多用于单个应用内部
  • 发布订阅模式,则更多的是一种跨应用的模式(cross-application pattern),比如我们常用的消息中间件

可以说出几种设计模式在开发中的实际应用,理解框架源码中对设计模式的应用

 

 

 JS 常用的六种设计模式介绍 - 掘金 (juejin.cn)

单例模式:vuex

优点: 节约资源,保证访问的一致性。

缺点: 扩展性不友好,因为单例模式一般自行实例化,没有接口。

 

工厂模式:根据不同的参数,返回不同类的实例。

将对象的创建与对象的实现分离。实现复杂,但使用简单。工厂会给我们提供一个工厂方法,我们直接去调用即可。

例子就是框架中在生成虚拟DOM的时候提供createElement来生成Vnode。

另外就是vue-router 中使用了工厂模式的思想来获得响应路由控制类的实例,this.history 用来保存路由实例。

优点:

  1. 良好的封装,访问者无需了解创建过程,代码结构清晰。
  1. 扩展性良好,通过工厂方法隔离了用户和创建流程,符合开闭原则。
  1. 解耦了高层逻辑和底层产品类,符合最少知识原则,不需要的就不要去交流;

缺点:

给系统增加了抽象性,带来了额外的系统复杂度,不能滥用。(合理抽象能提高系统维护性,但可能会提高阅读难度,还是需要合理看待)


代理模式
ES6里面的Proxy和Jquery.proxy
  • 代理模式能将代理对象与被调用对象分离,降低了系统的耦合度。代理模式在客户端和目标对象之间起到一个中介作用,这样可以起到保护目标对象的作用
  • 代理对象可以扩展目标对象的功能;通过修改代理对象就可以了,符合开闭原则
 
 
 
 
适配器模式
例子:vue中的computed

适配器与代理模式相似

  • 适配器模式: 提供一个不同的接口(如不同版本的插头)
  • 代理模式: 提供一模一样的接口
用于解决兼容问题,接口/方法/数据不兼容,将其转换成访问者期望的格式进行使用。
例子:组件针对不同的数据来源分别采用不同的渲染。保持了组件的单一职责。

优点: 可以使原有逻辑得到更好的复用,有助于避免大规模改写现有代码;

缺点: 会让系统变得零乱,明明调用 A,却被适配到了 B,如果滥用,那么对可阅读性不太友好。

 

装饰器模式

在不改变原对象的基础上,增加新属性/方法/功能。

 

策略模式

定义一系列算法,根据输入的参数决定使用哪个算法。算法的实现和算法的使用分开

  • Context :封装上下文,根据需要调用需要的策略,屏蔽外界对策略的直接调用,只对外提供一个接口,根据需要调用对应的策略;
  • Strategy :策略,含有具体的算法,其方法的外观相同,因此可以互相代替;
  • StrategyMap :所有策略的合集,供封装上下文调用;

 

 观察者模式
一个对象(称为subject)维持一系列依赖于它的对象(称为observer),将有关状态的任何变更自动通知给它们(观察者)。
 
发布订阅模式
 
 
 
posted @   不想做混子的奋斗远  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2022-03-06 acwing-特别数的和
点击右上角即可分享
微信分享提示
主题色彩