设计模式之中介者模式(mediator模式)
- 引入中介者模式
- 中介者模式實例
- 中介者模式分析
引入中介者模式
大家想象一下有十個人要共同完成一個工作,他們要互相合作和溝通,并且根據對方的通知可能要改變自己的狀態,但這通常會帶來很多問題,流程過于復雜,使得每個人不僅要專注于自己的事情,還要與他人進行溝通,得到通知,需要兼顧很多狀態的變化。這時候,我們考慮可以引入一個類似上帝視角的角色,就是引入一個中介者,他來負責接受每個人的通知,并將變化發送所需要的人去,就是要他來控制并調節工作的進度和細節,這個人往往是從整體考慮的,所以使得每個人工作者只需要考慮自己的問題,一旦有了變化,就通知仲裁者,交給仲裁者去決定就可以了。 所以最后就變成了,整個團隊的交流過程,組員向中介者報告,中介者向組員下達只命令。 這在現實生活中也是常見的,每個部門通常都會有一個領導人,每個班級有一個班長,往往是班長負責接受同學們的信息,然后將上面的信息從班長這里發給同學們,這里的班長就相當于一個仲裁者,同學們就相當于組員。
這就是中介者模式的基本思想,mediator有仲裁者和中介者的意思,一方面,當麻煩事情發生的時候,通知仲裁者,當發生設計全體組員的事情時,也通知仲裁者。當仲裁者下達指示的時候,組員會立即執行。團隊組員之間不再互相溝通并私自做決定,而是發生任何事情都像仲裁者報告。另一方面,仲裁者在整個團隊的角度上對組員報告的事情進行決定。
中介者模式的實例
我們通過一個gui程序來實現一個簡單的仲裁者模式
看上圖是一個我們經常見的登錄框。通常登錄框就設計很多狀態的變化,比如我們這個例子就要實現如下的邏輯
首先,如果選擇用戶登錄,那么用戶名輸入框處于啟用狀態,但密碼輸入框處于禁用狀態,如下圖
如果用戶輸入了用戶名,密碼框就啟用,如下圖
如果又刪掉了用戶名,那么密碼又變回禁用狀態
如果選擇游客登錄,就都處于禁用狀態。
假設我們有這樣的需求,那么我們應該如何編寫程序呢? 最先的想法就是,每個控件分別分別接受相關控件的狀態,根據不同的狀態在改變自己的狀態。這樣做是可以實現功能的,但是假設這時候我們新加一個控件進來,那么由于這個邏輯分散在各個控件的代碼中,所以我們修改起來非常麻煩,而且每個控件都充斥著狀態控制的代碼,很臃腫,控件應該專注于實現自己的邏輯。 因為這些控件都相互關聯,相互制約的,全部耦合在一起。 根據面向對象的設計原則,我們應該盡量對象過度耦合,實現松耦合的狀態。
于是,我們就可以利用中介者模式,每個控件發生了變化,我們就把變化發給中介者,中介者統一來處理,這樣控件就只需要專注于自己的實現就行了。
首先看類圖:
首先,定義Mediator接口
public interface Mediator {public abstract void createColleagues();public abstract void colleagueChanged(); }復制代碼定義Colleague接口
public interface Colleague {public abstract void setMediator(Mediator mediator);public abstract void setColleagueEnabled(boolean enabled); }復制代碼實現三個colleague類:
import java.awt.Button;public class ColleagueButton extends Button implements Colleague {private Mediator mediator;public ColleagueButton(String caption) {super(caption);}public void setMediator(Mediator mediator) { // 保存Mediatorthis.mediator = mediator;}public void setColleagueEnabled(boolean enabled) { // Mediator下達啟用/禁用的指示 setEnabled(enabled);} }復制代碼import java.awt.Checkbox; import java.awt.CheckboxGroup; import java.awt.event.ItemListener; import java.awt.event.ItemEvent;public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {private Mediator mediator;public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) { // 構造函數 super(caption, group, state);}public void setMediator(Mediator mediator) { // 保存Mediatorthis.mediator = mediator;}public void setColleagueEnabled(boolean enabled) { // Mediator下達啟用/禁用指示setEnabled(enabled);}public void itemStateChanged(ItemEvent e) { // 當狀態發生變化時通知Mediatormediator.colleagueChanged();} }復制代碼import java.awt.TextField; import java.awt.Color; import java.awt.event.TextListener; import java.awt.event.TextEvent;public class ColleagueTextField extends TextField implements TextListener, Colleague {private Mediator mediator;public ColleagueTextField(String text, int columns) { // 構造函數super(text, columns);}public void setMediator(Mediator mediator) { // 保存Mediatorthis.mediator = mediator;}public void setColleagueEnabled(boolean enabled) { // Mediator下達啟用/禁用的指示setEnabled(enabled);setBackground(enabled ? Color.white : Color.lightGray);}public void textValueChanged(TextEvent e) { // 當文字發生變化時通知Mediatormediator.colleagueChanged();} }復制代碼最后實現具體的中介者對象
import java.awt.Frame; import java.awt.Label; import java.awt.Color; import java.awt.CheckboxGroup; import java.awt.GridLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent;public class LoginFrame extends Frame implements ActionListener, Mediator {private ColleagueCheckbox checkGuest;private ColleagueCheckbox checkLogin;private ColleagueTextField textUser;private ColleagueTextField textPass;private ColleagueButton buttonOk;private ColleagueButton buttonCancel;// 構造函數。// 生成并配置各個Colleague后,顯示對話框。public LoginFrame(String title) {super(title);setBackground(Color.lightGray);// 使用布局管理器生成4×2窗格setLayout(new GridLayout(4, 2));// 生成各個ColleaguecreateColleagues();// 配置add(checkGuest);add(checkLogin);add(new Label("Username:"));add(textUser);add(new Label("Password:"));add(textPass);add(buttonOk);add(buttonCancel);// 設置初始的啟用起用/禁用狀態colleagueChanged();// 顯示pack();show();}// 生成各個Colleague。public void createColleagues() {// 生成CheckboxGroup g = new CheckboxGroup();checkGuest = new ColleagueCheckbox("Guest", g, true);checkLogin = new ColleagueCheckbox("Login", g, false);textUser = new ColleagueTextField("", 10);textPass = new ColleagueTextField("", 10);textPass.setEchoChar('*');buttonOk = new ColleagueButton("OK");buttonCancel = new ColleagueButton("Cancel");// 設置MediatorcheckGuest.setMediator(this);checkLogin.setMediator(this);textUser.setMediator(this);textPass.setMediator(this);buttonOk.setMediator(this);buttonCancel.setMediator(this);// 設置ListenercheckGuest.addItemListener(checkGuest);checkLogin.addItemListener(checkLogin);textUser.addTextListener(textUser);textPass.addTextListener(textPass);buttonOk.addActionListener(this);buttonCancel.addActionListener(this);}// 接收來自于Colleage的通知然后判斷各Colleage的啟用/禁用狀態。public void colleagueChanged() {if (checkGuest.getState()) { // Guest modetextUser.setColleagueEnabled(false);textPass.setColleagueEnabled(false);buttonOk.setColleagueEnabled(true);} else { // Login modetextUser.setColleagueEnabled(true);userpassChanged();}}// 當textUser或是textPass文本輸入框中的文字發生變化時// 判斷各Colleage的啟用/禁用狀態private void userpassChanged() {if (textUser.getText().length() > 0) {textPass.setColleagueEnabled(true);if (textPass.getText().length() > 0) {buttonOk.setColleagueEnabled(true);} else {buttonOk.setColleagueEnabled(false);}} else {textPass.setColleagueEnabled(false);buttonOk.setColleagueEnabled(false);}}public void actionPerformed(ActionEvent e) {System.out.println(e.toString());System.exit(0);} } 復制代碼Main類
import java.awt.*; import java.awt.event.*;public class Main {static public void main(String args[]) {new LoginFrame("Mediator Sample");} } 復制代碼運行結果
中介者模式分析
中介者模式主要有幾個角色
- 中介者 就是負責定義控制邏輯,接受來自組員的消息并處理的接口,對應實例中的Mediator接口
- 具體的中介者 實現接口,并根據不同的需求,做出不同的邏輯
- 同事組員Colleague 組員的接口,定義相應的方法
- 具體的組員 負責實現具體的組員邏輯,并將通知直接交給中介者執行
中介者模式的類圖:
總結
以上是生活随笔為你收集整理的设计模式之中介者模式(mediator模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序中用setData修改一个对象
- 下一篇: 联想云:借助云计算助力中国企业数字化转型