设计模式

设计模式,不是工具,是软件开发的哲学。它指导你如何去设计一个优秀的架构、编写一段健壮的代码、解决一个复杂的问题。
定个小目标

我是程序员,我想写出更加优雅的代码

观察者模式?

定义

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

角色组成
  1. Subject 抽象主题目标:维护一些列的观察者,提供添加或删除观察者的接口
  2. Observer 抽象观察者:为目标状态发生改变时需要通知的对象提供一个接口
  3. ConcreteSubject 具体主题目标:发生变化时通知观察者
  4. ConcreteObserver 具体观察者:实现具体的更新方法

观察者模式类图.png

优缺点
  • 优点:观察者和被观察之间是抽象耦合,容易扩展
  • 缺点:(Java中消息通知默认是顺序执行,而Javascript异步实现)多级触发效率问题
使用场景
  • 关联行为场景
  • 事件多级触发场景
  • 跨系统的消息交换场景
注意事项

双重身份观察者,建议一个观察者模式实现中,最多只有一个对象既是观察者也是被观察者,避免形成复杂的广播链,降低系统可维护性。

改造
  • 观察者和被观察者之间的消息沟通:观察者的update方法接收两个参数,一个是被观察者,一个是DTO数据传输对象
  • 观察者响应方式:一个观察者多个被观察者,采用多线程技术或缓存技术完成响应
  • 被观察者尽量自己做主:不是所有的改变都需要通知观察者,先判断一下
观察者模式 vs 发布订阅模式

观察者模式vs发布订阅者模式.png

vue2.x中的应用
  • 被观察者:data / prop
  • 观察者:watcher
  • 调度中心:dep

https://ustbhuangyi.github.io...

vue2.x 响应式原理
  • 核心:ES5的Object.defineProperty(obj, prop, descriptor) (不兼容IE8及以下浏览器)

    get是给属性提供一个getter方法,每次访问该属性会触发getter方法,setter提供属性修改时触发的setter方法

    (采用数据劫持结合发布-订阅者模式,通过Object.defineProperty()劫持各个属性的getter和setter,在数据变动时发布消息给订阅者,触发相应的监听回调)

  • 初始化:Vue的初始化阶段,会对data/props进行初始化操作,遍历data/props,(observe/ defineReactive方法)内部调用Object.defineProperty给每个属性加上getter、setter,getter用于依赖收集,setter用于派发更新;
  • 依赖收集:核心是一个Dep,Dep是连接数据和对应观察者的桥梁,每个对象的getter都持有一个dep实例,(访问数据)触发getter时,会调用dep.depend方法,让当前watcher订阅数据,为后面的数据变化通知做准备(每次添加完新的订阅,会移除旧的订阅)
  • 派发更新:当修改响应数据时,会触发setter,调用dep.notify()方法,通知所有订阅者,也就是watcher触发更新

代理模式

定义

为其他对象提供一种代理以控制对这个对象的访问。

角色组成
  1. Subject 抽象主题
  2. RealSubject 具体主题:被代理角色,业务逻辑的具体执行者
  3. Proxy 代理:代理类

代理模式类图.png

优缺点
  • 优点:职责清晰;高扩展性;智能化
  • 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢;实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景
  • 远程代理:为一个对象在不同的地址空间提供局部代表,隐藏一个对象存在与不同地址空间的事实
  • 虚拟代理:根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象
  • 安全代理:用来控制真实对象访问时的权限
  • 智能引用:调用真实对象时,代理处理一些额外的事。
扩展
  • 普通代理:只能访问代理角色,不能访问真实角色(调用者只知道代理,不知道真实角色)
  • 强制代理:必须通过真实角色找到代理角色
  • 动态代理:AOP面向切面编程
通晓23种设计模式,你可以站在一个更高的层次去赏析程挂·序代码、软件设计、架构,完成代码工人到架构师的蜕变。真正的理解设计模式,需要工作经验的积累。
参考资料

《设计模式之蝉》

Z同学学习总结:

观察者模式:

观察者模式适用场景,一个功能的变化会影响到其他模块产生对应自己的变化的操作,这种场景就适用用来适用观察者模式。如:直播送礼物,送礼物以后,用户的等级、经验,与直播的亲密度、主播的榜单、用户在主播房间内的榜单排行,通知弹幕下发礼物特效等等。也就是送礼物操作以后会影响到其他模块进行操作进行变化,这种场景就比较适合用观察者模式。

观察者模式里面并没有实现观察者和订阅者的解耦,同时我们也可以引用外部组件实现观察订阅模式,如引入消息队列,如kafka,引入外部组件的坏处是,当引入的外部组件每多一个,系统出问题的时候,排查问题的复杂性就会增加。

代理模式:
我当下的理解是,A想向C通信,这个过程中,A又有点害羞,不想直接和C通信,这个时候想通过B给C通信,那么A和B都有类似的实现,然后A传给B,调用B的方法和C通信。

设计模式学习和使用:

讲设计模式的时候大家觉得都不是很好讲,其中一方面是我们日常使用的少,没有体会到使用设计模式的优点和价值,另一方面也是我们并没有体会到设计模式的精髓,所以后者需要我们在后面的学习和使用中加深影响,更加深刻的理解设计模式。

我觉得设计模式和我们平常学习其他东西都要经历这几个阶段,知道有这个东西,然后去使用,发现用的不是很好,然后回过头再去仔细的看为什么这样使用,然后深刻理解以后,更好的应用在我们的代码和系统当中。

知道 - 使用 - 理解为什么 - 更好的应用


新数学习小组
13 声望3 粉丝

新数学习小组: