中介者模式
Mediator Pattern
用一個中介對象來封裝一系列的對象互動,中介者使各對象不需要顯式地互相引用,進而使其耦合松散,降低多個對象和類之間的通信複雜性,而且可以獨立地改變它們之間的互動,中介者類通常處理不同類之間的通信。中介者模式又稱為調停者模式,是一種對象行為型模式。
描述
在軟體工程中,中介者模式定義了一個對象,該對象封裝了一組對象之間的互動方式,由于該模式可以更改程式的運作行為,是以該模式被視為行為模式。在使用者與使用者直接聊天的設計方案中,使用者對象之間存在很強的關聯性,将導緻系統出現如下問題:系統結構複雜,對象之間存在大量的互相關聯和調用,若有一個對象發生變化,則需要跟蹤和該對象關聯的其他所有對象,并進行适當處理;對象可重用性差,由于一個對象和其他對象具有很強的關聯,若沒有其他對象的支援,一個對象很難被另一個系統或子產品重用,這些對象表現出來更像一個不可分割的整體,職責較為混亂。
系統擴充性低:增加一個新的對象需要在原有相關對象上增加引用,增加新的引用關系也需要調整原有對象,系統耦合度很高,對象操作很不靈活,擴充性差;在面向對象的軟體設計與開發過程中,根據單一職責原則,我們應該盡量将對象細化,使其隻負責或呈現單一的職責。對于一個子產品,可能由很多對象構成,而且這些對象之間可能存在互相的引用,為了減少對象兩兩之間複雜的引用關系,使之成為一個松耦合的系統,我們需要使用中介者模式。
優點
- 簡化了對象之間的互動。
- 将各同僚解耦。
- 減少子類生成。
- 可以簡化各同僚類的設計和實作。
缺點
- 在具體中介者類中包含了同僚之間的互動細節,可能會導緻具體中介者類非常複雜,使得系統難以維護。
适用環境
- 系統中對象之間存在複雜的引用關系,産生的互相依賴關系結構混亂且難以了解。
- 一個對象由于引用了其他很多對象并且直接和這些對象通信,導緻難以複用該對象。
- 想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實作,在中介者中定義對象。
- 互動的公共行為,如果需要改變行為則可以增加新的中介者類。
實作
// 聊天室作為中介 提供給使用者聊天功能
class ChatRoom {
showMessage(user, message) {
const time = new Date();
const sender = user.getName();
console.log(`${time} [${sender}]: ${message}`)
}
}
class User {
constructor(name, chatMediator) {
this._name = name;
this.chatMediator = chatMediator;
}
getName() {
return this._name;
}
send(message) {
this.chatMediator.showMessage(this, message);
}
}
(function(){
const mediator = new ChatRoom();
const john = new User("John Doe", mediator);
const jane = new User("Jane Doe", mediator);
john.send("Hi there!"); // Tue Nov 10 2020 19:36:07 GMT+0800 (China Standard Time) [John Doe]: Hi there!
jane.send("Hey!"); // Tue Nov 10 2020 19:36:07 GMT+0800 (China Standard Time) [Jane Doe]: Hey!
})();
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://www.runoob.com/design-pattern/mediator-pattern.html
https://github.com/sohamkamani/javascript-design-patterns-for-humans#-mediator
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/mediator.html