如何优雅地简化对象之间的耦合关系?
前言
开发过程有个原则叫"最少知识原则",也就是说一个对象尽可能少得了解另外一个对象,这样才能降低耦合性,否则每一次改动都可能产生较多的关联影响。"中介者模式"和"发布订阅模式"很好地体现了"最少知识原则",并且它两有一些相似性,容易让人不好区分,所以现在放在一起进行讨论和学习。
中介者模式(mediator)
用一个中介对象来封装一系列的对象交互
优点:降低了对象间的耦合性,可以独立地修改它们之间的交互。
缺点:由于对象之间交互的复杂性转移到了中介对象,中介对象往往变得巨大和难维护。
介绍完中介者模式的概念以及它的优缺点,我们再来个场景试试代码。
需求是:有多个对象,当对象全部处于完成状态时,再执行余下操作。
// 中介者类
class Mediator {
constructor () {
this.partner = {}
Array.from(arguments).forEach(key => this.partner[key] = false)
}
success (key) {
this.partner[key] = true
this.checkAllSuccess()
}
fail (key) {
this.partner[key] = false
this.checkAllSuccess()
}
checkAllSuccess () {
console.log(!Object.values(this.partner).includes(false) ? '全部完成!' : '未全部完成!')
}
}
// 对象类,用于生成有交互关系的对象
class Partner {
constructor (name) {
this.name = name
}
success () {
mediator.success(this.name)
}
fail () {
mediator.fail(this.name)
}
}
let mediator = new Mediator('aa', 'bb')
let aa = new Partner('aa')
let bb = new Partner('bb')
aa.success() // 未全部完成!
bb.success() // 全部完成!
总结:当多个对象之间存在交互行为时,优先考虑采用中介者模式。
发布订阅者(观察者模式)
它定义了对象之间的一种一对多的依赖关系,当一个对象变化时,所有依赖的对象都讲得到通知。
使用发布订阅者的优点主要还是能够使对象之间解耦。
上个最简洁的使用框架
class Observer {
subs = []
add (obj) {
this.subs.push(obj)
}
remove (key) {
this.subs = this.subs.filter(obj => obj.key !== key)
}
notify () {
subs.forEach(obj => {
obj.fn()
})
}
}
let observer = new Observer()
observer.add({
key: 'a',
fn: () => {console.log('a')}
})
observer.add({
key: 'b',
fn: () => {console.log('b')}
})
observer.notify()
总结
中介者和观察者很相似,相似就在于它两均有发布功能。两种的差别主要在于:中介者强调同事(colleague)类之间的交互,而发布订阅者强调目标改变之后对订阅者的统一通讯。我觉得应该可以说中介者包含了发布订阅者。中介者的用户可以订阅和发布,发布订阅则只有一处发布,用户只能订阅。
Gitalking ...
Be the first guy leaving a comment!