日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
設(shè)計(jì)模式系列—中介者模式

模式定義

定義一個(gè)中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合松散,且可以獨(dú)立地改變它們之間的交互。中介者模式又叫調(diào)停模式,它是迪米特法則的典型應(yīng)用。

  • 迪米特法則(Law of Demeter,LoD)又叫作最少知識原則(Least Knowledge Principle,LKP),產(chǎn)生于 1987 年美國東北大學(xué)(Northeastern University)的一個(gè)名為迪米特(Demeter)的研究項(xiàng)目,由伊恩·荷蘭(Ian Holland)提出,被 UML 創(chuàng)始者之一的布奇(Booch)普及,后來又因?yàn)樵诮?jīng)典著作《程序員修煉之道》(The Pragmatic Programmer)提及而廣為人知。
  • 迪米特法則的定義是:只與你的直接朋友交談,不跟“陌生人”說話(Talk only to your immediate friends and not to strangers)。其含義是:如果兩個(gè)軟件實(shí)體無須直接通信,那么就不應(yīng)當(dāng)發(fā)生直接的相互調(diào)用,可以通過第三方轉(zhuǎn)發(fā)該調(diào)用。其目的是降低類之間的耦合度,提高模塊的相對獨(dú)立性。
  • 迪米特法則中的“朋友”是指:當(dāng)前對象本身、當(dāng)前對象的成員對象、當(dāng)前對象所創(chuàng)建的對象、當(dāng)前對象的方法參數(shù)等,這些對象同當(dāng)前對象存在關(guān)聯(lián)、聚合或組合關(guān)系,可以直接訪問這些對象的方法。

模板實(shí)現(xiàn)如下:

 
 
 
 
  1. package com.niuh.designpattern.mediator.v1;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5.  * 

  6.  * 中介者模式
  7.  * 

  8.  */
  9. public class MediatorPattern {
  10.     public static void main(String[] args) {
  11.         Mediator md = new ConcreteMediator();
  12.         Colleague c1, c2;
  13.         c1 = new ConcreteColleague1();
  14.         c2 = new ConcreteColleague2();
  15.         md.register(c1);
  16.         md.register(c2);
  17.         c1.send();
  18.         System.out.println("==============");
  19.         c2.send();
  20.     }
  21. }
  22. //抽象中介者
  23. abstract class Mediator {
  24.     public abstract void register(Colleague colleague);
  25.     public abstract void relay(Colleague cl); //轉(zhuǎn)發(fā)
  26. }
  27. //具體中介者
  28. class ConcreteMediator extends Mediator {
  29.     private List colleagues = new ArrayList();
  30.     public void register(Colleague colleague) {
  31.         if (!colleagues.contains(colleague)) {
  32.             colleagues.add(colleague);
  33.             colleague.setMedium(this);
  34.         }
  35.     }
  36.     public void relay(Colleague cl) {
  37.         for (Colleague ob : colleagues) {
  38.             if (!ob.equals(cl)) {
  39.                 ((Colleague) ob).receive();
  40.             }
  41.         }
  42.     }
  43. }
  44. //抽象同事類
  45. abstract class Colleague {
  46.     protected Mediator mediator;
  47.     public void setMedium(Mediator mediator) {
  48.         this.mediator = mediator;
  49.     }
  50.     public abstract void receive();
  51.     public abstract void send();
  52. }
  53. //具體同事類
  54. class ConcreteColleague1 extends Colleague {
  55.     public void receive() {
  56.         System.out.println("具體同事類1收到請求。");
  57.     }
  58.     public void send() {
  59.         System.out.println("具體同事類1發(fā)出請求。");
  60.         mediator.relay(this); //請中介者轉(zhuǎn)發(fā)
  61.     }
  62. }
  63. //具體同事類
  64. class ConcreteColleague2 extends Colleague {
  65.     public void receive() {
  66.         System.out.println("具體同事類2收到請求。");
  67.     }
  68.     public void send() {
  69.         System.out.println("具體同事類2發(fā)出請求。");
  70.         mediator.relay(this); //請中介者轉(zhuǎn)發(fā)
  71.     }
  72. }

結(jié)果實(shí)現(xiàn)如下:

  • 具體同事類1發(fā)出請求。
  • 具體同事類2收到請求。
  • 具體同事類2發(fā)出請求。
  • 具體同事類1收到請求。

解決的問題

對象與對象之間存在大量的關(guān)聯(lián)關(guān)系,這樣勢必會導(dǎo)致系統(tǒng)的結(jié)構(gòu)變得很復(fù)雜,同時(shí)若一個(gè)對象發(fā)生改變,我們也需要跟蹤與之相關(guān)聯(lián)的對象,同時(shí)做出相應(yīng)的處理。

模式組成

中介者模式實(shí)現(xiàn)的關(guān)鍵是找出“中介者”。

實(shí)例說明

實(shí)例概況

用中介者模式編寫一個(gè)“北京房地產(chǎn)交流平臺”程序。

分析:北京房地產(chǎn)交流平臺是“房地產(chǎn)中介公司”提供給“賣方客戶”與“買方客戶”進(jìn)行信息交流的平臺,比較適合用中介者模式來實(shí)現(xiàn)。

使用步驟

步驟1:定義一個(gè)中介公司(Medium)接口,它是抽象中介者,它包含了客戶注冊方法 register(Customer member) 和信息轉(zhuǎn)發(fā)方法 relay(String from,String ad);

 
 
 
 
  1. interface Medium {
  2.     //客戶注冊
  3.     void register(Customer member);
  4.     //轉(zhuǎn)發(fā)
  5.     void relay(String from, String ad);
  6. }

步驟2:定義一個(gè)北京房地產(chǎn)中介(EstateMedium)公司,它是具體中介者類,它包含了保存客戶信息的 List 對象,并實(shí)現(xiàn)了中介公司中的抽象方法。

 
 
 
 
  1. //具體中介者:房地產(chǎn)中介
  2. class EstateMedium implements Medium {
  3.     private List members = new ArrayList();
  4.     public void register(Customer member) {
  5.         if (!members.contains(member)) {
  6.             members.add(member);
  7.             member.setMedium(this);
  8.         }
  9.     }
  10.     public void relay(String from, String ad) {
  11.         for (Customer ob : members) {
  12.             String name = ob.getName();
  13.             if (!name.equals(from)) {
  14.                 ((Customer) ob).receive(from, ad);
  15.             }
  16.         }
  17.     }
  18. }

步驟3:定義一個(gè)客戶(Qistomer)類,它是抽象同事類,其中包含了中介者的對象,和發(fā)送信息的 send(String ad) 方法與接收信息的 receive(String from,Stringad) 方法的接口,由于本程序是窗體程序,所以本類繼承 JPmme 類,并實(shí)現(xiàn)動作事件的處理方法 actionPerformed(ActionEvent e)。

 
 
 
 
  1. //抽象同事類:客戶
  2. abstract class Customer extends JFrame implements ActionListener {
  3.     private static final long serialVersionUID = -7219939540794786080L;
  4.     protected Medium medium;
  5.     protected String name;
  6.     JTextField SentText;
  7.     JTextArea ReceiveArea;
  8.     public Customer(String name) {
  9.         super(name);
  10.         this.name = name;
  11.     }
  12.     void ClientWindow(int x, int y) {
  13.         Container cp;
  14.         JScrollPane sp;
  15.         JPanel p1, p2;
  16.         cp = this.getContentPane();
  17.         SentText = new JTextField(18);
  18.         ReceiveArea = new JTextArea(10, 18);
  19.         ReceiveArea.setEditable(false);
  20.         p1 = new JPanel();
  21.         p1.setBorder(BorderFactory.createTitledBorder("接收內(nèi)容:"));
  22.         p1.add(ReceiveArea);
  23.         sp = new JScrollPane(p1);
  24.         cp.add(sp, BorderLayout.NORTH);
  25.         p2 = new JPanel();
  26.         p2.setBorder(BorderFactory.createTitledBorder("發(fā)送內(nèi)容:"));
  27.         p2.add(SentText);
  28.         cp.add(p2, BorderLayout.SOUTH);
  29.         SentText.addActionListener(this);
  30.         this.setLocation(x, y);
  31.         this.setSize(250, 330);
  32.         this.setResizable(false); //窗口大小不可調(diào)整
  33.         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  34.         this.setVisible(true);
  35.     }
  36.     public void actionPerformed(ActionEvent e) {
  37.         String tempInfo = SentText.getText().trim();
  38.         SentText.setText("");
  39.         this.send(tempInfo);
  40.     }
  41.     public String getName() {
  42.         return name;
  43.     }
  44.     public void setMedium(Medium medium) {
  45.         this.medium = medium;
  46.     }
  47.     public abstract void send(String ad);
  48.     public abstract void receive(String from, String ad);
  49. }

步驟4:定義賣方(Seller)類和買方(Buyer)類,它們是具體同事類,是客戶(Customer)類的子類,它們實(shí)現(xiàn)了父類中的抽象方法,通過中介者類進(jìn)行信息交流。

 
 
 
 
  1. //具體同事類:賣方
  2. class Seller extends Customer {
  3.     private static final long serialVersionUID = -1443076716629516027L;
  4.     public Seller(String name) {
  5.         super(name);
  6.         ClientWindow(50, 100);
  7.     }
  8.     public void send(String ad) {
  9.         ReceiveArea.append("我(賣方)說: " + ad + "\n");
  10.         //使?jié)L動條滾動到最底端
  11.         ReceiveArea.setCaretPosition(ReceiveArea.getText().length());
  12.         medium.relay(name, ad);
  13.     }
  14.     public void receive(String from, String ad) {
  15.         ReceiveArea.append(from + "說: " + ad + "\n");
  16.         //使?jié)L動條滾動到最底端
  17.         ReceiveArea.setCaretPosition(ReceiveArea.getText().length());
  18.     }
  19. }
  20. //具體同事類:買方
  21. class Buyer extends Customer {
  22.     private static final long serialVersionUID = -474879276076308825L;
  23.     public Buyer(String name) {
  24.         super(name);
  25.         ClientWindow(350, 100);
  26.     }
  27.     public void send(String ad) {
  28.         ReceiveArea.append("我(買方)說: " + ad + "\n");
  29.         //使?jié)L動條滾動到最底端
  30.         ReceiveArea.setCaretPosition(ReceiveArea.getText().length());
  31.         medium.relay(name, ad);
  32.     }
  33.     public void receive(String from, String ad) {
  34.         ReceiveArea.append(from + "說: " + ad + "\n");
  35.         //使?jié)L動條滾動到最底端
  36.         ReceiveArea.setCaretPosition(ReceiveArea.getText().length());
  37.     }
  38. }

輸出結(jié)果

優(yōu)點(diǎn)

  1. 降低了對象之間的耦合性,使得對象易于獨(dú)立地被復(fù)用。
  2. 將對象間的一對多關(guān)聯(lián)轉(zhuǎn)變?yōu)橐粚σ坏年P(guān)聯(lián),提高系統(tǒng)的靈活性,使得系統(tǒng)易于維護(hù)和擴(kuò)展。

缺點(diǎn)

當(dāng)同事類太多時(shí),中介者的職責(zé)將很大,它會變得復(fù)雜而龐大,以至于系統(tǒng)難以維護(hù)。

應(yīng)用場景

  • 當(dāng)對象之間存在復(fù)雜的網(wǎng)狀結(jié)構(gòu)關(guān)系而導(dǎo)致依賴關(guān)系混亂且難以復(fù)用時(shí)。
  • 當(dāng)想創(chuàng)建一個(gè)運(yùn)行于多個(gè)類之間的對象,又不想生成新的子類時(shí)。

模式的擴(kuò)展

在實(shí)際開發(fā)中,通常采用以下兩種方法來簡化中介者模式,使開發(fā)變得更簡單。

  1. 不定義中介者接口,把具體中介者對象實(shí)現(xiàn)成為單例。
  2. 同事對象不持有中介者,而是在需要的時(shí)候直接獲取中介者對象并調(diào)用。

程序代碼如下:

 
 
 
 
  1. package com.niuh.designpattern.mediator.v3;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5.  * 

  6.  * 簡化中介者模式
  7.  * 

  8.  */
  9. public class SimpleMediatorPattern {
  10.     public static void main(String[] args) {
  11.         SimpleColleague c1, c2;
  12.         c1 = new SimpleConcreteColleague1();
  13.         c2 = new SimpleConcreteColleague2();
  14.         c1.send();
  15.         System.out.println("==============");
  16.         c2.send();
  17.     }
  18. }
  19. //簡單單例中介者
  20. class SimpleMediator {
  21.     private static SimpleMediator smd = new SimpleMediator();
  22.     private List colleagues = new ArrayList();
  23.     private SimpleMediator() {
  24.     }
  25.     public static SimpleMediator getMedium() {
  26.         return (smd);
  27.     }
  28.     public void register(SimpleColleague colleague) {
  29.         if (!colleagues.contains(colleague)) {
  30.             colleagues.add(colleague);
  31.         }
  32.     }
  33.     public void relay(SimpleColleague scl) {
  34.         for (SimpleColleague ob : colleagues) {
  35.             if (!ob.equals(scl)) {
  36.                 ((SimpleColleague) ob).receive();
  37.             }
  38.         }
  39.     }
  40. }
  41. //抽象同事類
  42. interface SimpleColleague {
  43.     void receive();
  44.     void send();
  45. }
  46. //具體同事類
  47. class SimpleConcreteColleague1 implements SimpleColleague {
  48.     SimpleConcreteColleague1() {
  49.         SimpleMediator smd = SimpleMediator.getMedium();
  50.         smd.register(this);
  51.     }
  52.     public void receive() {
  53.         System.out.println("具體同事類1:收到請求。");
  54.     }
  55.     public void send() {
  56.         SimpleMediator smd = SimpleMediator.getMedium();
  57.         System.out.println("具體同事類1:發(fā)出請求...");
  58.         smd.relay(this); //請中介者轉(zhuǎn)發(fā)
  59.     }
  60. }
  61. //具體同事類
  62. class SimpleConcreteColleague2 implements SimpleColleague {
  63.     SimpleConcreteColleague2() {
  64.         SimpleMediator smd = SimpleMediator.getMedium();
  65.         smd.register(this);
  66.     }
  67.     public void receive() {
  68.         System.out.println("具體同事類2:收到請求。");
  69.     }
  70.     public void send() {
  71.         SimpleMediator smd = SimpleMediator.getMedium();
  72.         System.out.println("具體同事類2:發(fā)出請求...");
  73.         smd.relay(this); //請中介者轉(zhuǎn)發(fā)
  74.     }
  75. }

輸出結(jié)果如下:

  • 具體同事類1:發(fā)出請求...
  • 具體同事類2:收到請求。
  • 具體同事類2:發(fā)出請求...
  • 具體同事類1:收到請求。

源碼中的應(yīng)用

 
 
 
 
  1. java.util.Timer
  2. java.util.concurrent.Executer#execute()
  3. java.util.concurrent.ExecuterService#submit()
  4. java.lang.reflect.Method#invoke()

PS:以上代碼提交在 Github


標(biāo)題名稱:設(shè)計(jì)模式系列—中介者模式
網(wǎng)址分享:http://www.dlmjj.cn/article/cddohpg.html