日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

协调多个对象之间的交互——中介者模式

發(fā)布時間:2024/2/28 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 协调多个对象之间的交互——中介者模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文轉(zhuǎn)載自 :http://blog.csdn.net/lovelion/article/details/8482952


騰訊公司推出的QQ作為一款免費的即時聊天軟件深受廣大用戶的喜愛,它已經(jīng)成為很多人學(xué)習(xí)、工作和生活的一部分(不要告訴我你沒有QQ哦,)。在QQ聊天中,一般有兩種聊天方式:第一種是用戶與用戶直接聊天第二種是通過QQ群聊天,如圖20-1所示。如果我們使用圖20-1(A)所示方式,一個用戶如果要與別的用戶聊天或發(fā)送文件,通常需要加其他用戶為好友,用戶與用戶之間存在多對多的聯(lián)系,這將導(dǎo)致系統(tǒng)中用戶之間的關(guān)系非常復(fù)雜,一個用戶如果要將相同的信息或文件發(fā)送給其他所有用戶,必須一個一個的發(fā)送,于是QQ群產(chǎn)生了,如圖20-1(B)所示,如果使用QQ群,一個用戶就可以向多個用戶發(fā)送相同的信息和文件而無須一一進行發(fā)送,只需要將信息或文件發(fā)送到群中或作為群共享即可,群的作用就是將發(fā)送者所發(fā)送的信息和文件轉(zhuǎn)發(fā)給每一個接收者用戶。通過引入群的機制,將極大減少系統(tǒng)中用戶之間的兩兩通信,用戶與用戶之間的聯(lián)系可以通過群來實現(xiàn)。

20-1 QQ聊天示意圖

?????? 在有些軟件中,某些類/對象之間的相互調(diào)用關(guān)系錯綜復(fù)雜,類似QQ用戶之間的關(guān)系,此時,我們特別需要一個類似“QQ群”一樣的中間類來協(xié)調(diào)這些類/對象之間的復(fù)雜關(guān)系,以降低系統(tǒng)的耦合度。有一個設(shè)計模式正為此而誕生,它就是本章將要介紹的中介者模式。

?

20.1?客戶信息管理窗口的初始設(shè)計

????? ?Sunny軟件公司欲開發(fā)一套CRM系統(tǒng),其中包含一個客戶信息管理模塊,所設(shè)計的“客戶信息管理窗口”界面效果圖如圖20-2所示:

20-2?“客戶信息管理窗口”界面圖

?????? Sunny公司開發(fā)人員通過分析發(fā)現(xiàn),在圖20-2中,界面組件之間存在較為復(fù)雜的交互關(guān)系:如果刪除一個客戶,要在客戶列表(List)中刪掉對應(yīng)的項,客戶選擇組合框(ComboBox)中客戶名稱也將減少一個;如果增加一個客戶信息,客戶列表中需增加一個客戶,且組合框中也將增加一項。

?????? 如果實現(xiàn)界面組件之間的交互是Sunny公司開發(fā)人員必須面對的一個問題?

????????Sunny公司開發(fā)人員對組件之間的交互關(guān)系進行了分析,結(jié)果如下:

?????? (1)?當(dāng)用戶單擊“增加”按鈕、“刪除”按鈕、“修改”按鈕或“查詢”按鈕時,界面左側(cè)的“客戶選擇組合框”、“客戶列表”以及界面中的文本框?qū)a(chǎn)生響應(yīng)。

?????? (2)?當(dāng)用戶通過“客戶選擇組合框”選中某個客戶姓名時,“客戶列表”和文本框?qū)a(chǎn)生響應(yīng)。

?????? (3)?當(dāng)用戶通過“客戶列表”選中某個客戶姓名時,“客戶選擇組合框”和文本框?qū)a(chǎn)生響應(yīng)。

????? 于是,Sunny公司開發(fā)人員根據(jù)組件之間的交互關(guān)系繪制了如圖20-3所示初始類圖:

20-3?“客戶信息管理窗口”原始類圖

????? 與類圖20-3所對應(yīng)的框架代碼片段如下:

[java]?view plaincopy
  • //按鈕類??
  • class?Button?{??
  • ????private?List?list;??
  • ????private?ComboBox?cb;??
  • ????private?TextBox?tb;??
  • ????......??
  • ??
  • ????//界面組件的交互??
  • ????public?void?change()?{??
  • ????????list.update();??
  • ????????cb.update();??
  • ????????tb.update();??
  • ????}??
  • ??
  • ????public?void?update()?{??
  • ????????......??
  • ????}??
  • ????......??
  • }??
  • ??
  • //列表框類??
  • class?List?{??
  • ????private?ComboBox?cb;??
  • ????private?TextBox?tb;??
  • ????......??
  • ??
  • //界面組件的交互??
  • ????public?void?change()?{??
  • ????????cb.update();??
  • ????????tb.update();??
  • ????}??
  • ??
  • ????public?void?update()?{??
  • ????????......??
  • ????}??
  • ????......????
  • }??
  • ??
  • //組合框類??
  • class?ComboBox?{??
  • ????private?List?list;??
  • ????private?TextBox?tb;??
  • ????......??
  • ??
  • //界面組件的交互??
  • ????public?void?change()?{??
  • ????????list.update();??
  • ????????tb.update();??
  • ????}??
  • ??
  • ????public?void?update()?{??
  • ????????......??
  • ????}??
  • ????......????
  • }??
  • ??
  • //文本框類??
  • class?TextBox?{??
  • ????public?void?update()?{??
  • ????????......??
  • ????}??
  • ????......????
  • }??
  • ????????分析圖20-3所示初始結(jié)構(gòu)圖和上述代碼,我們不難發(fā)現(xiàn)該設(shè)計方案存在如下問題:

    ???????(1)?系統(tǒng)結(jié)構(gòu)復(fù)雜且耦合度高:每一個界面組件都與多個其他組件之間產(chǎn)生相互關(guān)聯(lián)和調(diào)用,若一個界面組件對象發(fā)生變化,需要跟蹤與之有關(guān)聯(lián)的其他所有組件并進行處理,系統(tǒng)組件之間呈現(xiàn)一種較為復(fù)雜的網(wǎng)狀結(jié)構(gòu),組件之間的耦合度高。

    ?????? (2)?組件的可重用性差:由于每一個組件和其他組件之間都具有很強的關(guān)聯(lián),若沒有其他組件的支持,一個組件很難被另一個系統(tǒng)或模塊重用,這些組件表現(xiàn)出來更像一個不可分割的整體,而在實際使用時,我們往往需要每一個組件都能夠單獨重用,而不是重用一個由多個組件組成的復(fù)雜結(jié)構(gòu)。

    ?????? (3)?系統(tǒng)的可擴展性差:如果在上述系統(tǒng)中增加一個新的組件類,則必須修改與之交互的其他組件類的源代碼,將導(dǎo)致多個類的源代碼需要修改,同樣,如果要刪除一個組件也存在類似的問題,這違反了“開閉原則”,可擴展性和靈活性欠佳。

    ?????? 由于存在上述問題,Sunny公司開發(fā)人員不得不對原有系統(tǒng)進行重構(gòu),那如何重構(gòu)呢?大家想到了“迪米特法則”,引入一個“第三者”來降低現(xiàn)有系統(tǒng)中類之間的耦合度。由這個“第三者”來封裝并協(xié)調(diào)原有組件兩兩之間復(fù)雜的引用關(guān)系,使之成為一個松耦合的系統(tǒng),這個“第三者”又稱為“中介者”,中介者模式因此而得名。下面讓我們正式進入中介者模式的學(xué)習(xí),學(xué)會如何使用中介者類來協(xié)調(diào)多個類/對象之間的交互,以達到降低系統(tǒng)耦合度的目的。

    20.2 中介者模式概述

    ???????如果在一個系統(tǒng)中對象之間的聯(lián)系呈現(xiàn)為網(wǎng)狀結(jié)構(gòu),如圖20-4所示。對象之間存在大量的多對多聯(lián)系,將導(dǎo)致系統(tǒng)非常復(fù)雜,這些對象既會影響別的對象,也會被別的對象所影響,這些對象稱為同事對象,它們之間通過彼此的相互作用實現(xiàn)系統(tǒng)的行為。在網(wǎng)狀結(jié)構(gòu)中,幾乎每個對象都需要與其他對象發(fā)生相互作用,而這種相互作用表現(xiàn)為一個對象與另外一個對象的直接耦合,這將導(dǎo)致一個過度耦合的系統(tǒng)。

    20-4?對象之間存在復(fù)雜關(guān)系的網(wǎng)狀結(jié)構(gòu)

    ????? 中介者模式可以使對象之間的關(guān)系數(shù)量急劇減少,通過引入中介者對象,可以將系統(tǒng)的網(wǎng)狀結(jié)構(gòu)變成以中介者為中心的星形結(jié)構(gòu),如圖20-5所示。在這個星形結(jié)構(gòu)中,同事對象不再直接與另一個對象聯(lián)系,它通過中介者對象與另一個對象發(fā)生相互作用。中介者對象的存在保證了對象結(jié)構(gòu)上的穩(wěn)定,也就是說,系統(tǒng)的結(jié)構(gòu)不會因為新對象的引入帶來大量的修改工作。

    20-5?引入中介者對象的星型結(jié)構(gòu)

    ????? 如果在一個系統(tǒng)中對象之間存在多對多的相互關(guān)系,我們可以將對象之間的一些交互行為從各個對象中分離出來,并集中封裝在一個中介者對象中,并由該中介者進行統(tǒng)一協(xié)調(diào),這樣對象之間多對多的復(fù)雜關(guān)系就轉(zhuǎn)化為相對簡單的一對多關(guān)系。通過引入中介者來簡化對象之間的復(fù)雜交互,中介者模式是“迪米特法則”的一個典型應(yīng)用。

    ?

    ????? 中介者模式定義如下:

    中介者模式(Mediator Pattern):用一個中介對象(中介者)來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。中介者模式又稱為調(diào)停者模式,它是一種對象行為型模式。

    ????? 在中介者模式中,我們引入了用于協(xié)調(diào)其他對象/類之間相互調(diào)用的中介者類,為了讓系統(tǒng)具有更好的靈活性和可擴展性,通常還提供了抽象中介者,其結(jié)構(gòu)圖如圖20-6所示:

    20-6?中介者模式結(jié)構(gòu)圖

    ????? 在中介者模式結(jié)構(gòu)圖中包含如下幾個角色:

    ????? ●?Mediator(抽象中介者):它定義一個接口,該接口用于與各同事對象之間進行通信。

    ????? ●?ConcreteMediator(具體中介者):它是抽象中介者的子類,通過協(xié)調(diào)各個同事對象來實現(xiàn)協(xié)作行為,它維持了對各個同事對象的引用。

    ????? ●?Colleague(抽象同事類):它定義各個同事類公有的方法,并聲明了一些抽象方法來供子類實現(xiàn),同時它維持了一個對抽象中介者類的引用,其子類可以通過該引用來與中介者通信。

    ????? ●?ConcreteColleague(具體同事類):它是抽象同事類的子類;每一個同事對象在需要和其他同事對象通信時,先與中介者通信,通過中介者來間接完成與其他同事類的通信;在具體同事類中實現(xiàn)了在抽象同事類中聲明的抽象方法。

    ?

    ????? 中介者模式的核心在于中介者類的引入,在中介者模式中,中介者類承擔(dān)了兩方面的職責(zé):

    ???????(1)?中轉(zhuǎn)作用(結(jié)構(gòu)性):通過中介者提供的中轉(zhuǎn)作用,各個同事對象就不再需要顯式引用其他同事,當(dāng)需要和其他同事進行通信時,可通過中介者來實現(xiàn)間接調(diào)用。該中轉(zhuǎn)作用屬于中介者在結(jié)構(gòu)上的支持。

    ??????(2)?協(xié)調(diào)作用(行為性):中介者可以更進一步的對同事之間的關(guān)系進行封裝,同事可以一致的和中介者進行交互,而不需要指明中介者需要具體怎么做,中介者根據(jù)封裝在自身內(nèi)部的協(xié)調(diào)邏輯,對同事的請求進行進一步處理,將同事成員之間的關(guān)系行為進行分離和封裝。該協(xié)調(diào)作用屬于中介者在行為上的支持。

    ????? 在中介者模式中,典型的抽象中介者類代碼如下所示:

    [java]?view plaincopy
  • abstract?class?Mediator?{??
  • ????protected?ArrayList<Colleague>?colleagues;?//用于存儲同事對象??
  • ??
  • ????//注冊方法,用于增加同事對象??
  • ????public?void?register(Colleague?colleague)?{??
  • ????????colleagues.add(colleague);??
  • ????}??
  • ??
  • ????//聲明抽象的業(yè)務(wù)方法??
  • ????public?abstract?void?operation();??
  • }??
  • ?????? 在抽象中介者中可以定義一個同事類的集合,用于存儲同事對象并提供注冊方法,同時聲明了具體中介者類所具有的方法。在具體中介者類中將實現(xiàn)這些抽象方法,典型的具體中介者類代碼如下所示:

    [java]?view plaincopy
  • class?ConcreteMediator?extends?Mediator?{??
  • ????//實現(xiàn)業(yè)務(wù)方法,封裝同事之間的調(diào)用??
  • ????public?void?operation()?{??
  • ????????......??
  • ????????((Colleague)(colleagues.get(0))).method1();?//通過中介者調(diào)用同事類的方法??
  • ????????......??
  • ????}??
  • }??
  • ????? 在具體中介者類中將調(diào)用同事類的方法,調(diào)用時可以增加一些自己的業(yè)務(wù)代碼對調(diào)用進行控制。

    ????? 在抽象同事類中維持了一個抽象中介者的引用,用于調(diào)用中介者的方法,典型的抽象同事類代碼如下所示:

    [java]?view plaincopy
  • abstract?class?Colleague?{??
  • ????protected?Mediator?mediator;?//維持一個抽象中介者的引用??
  • ??????
  • ????public?Colleague(Mediator?mediator)?{??
  • ????????this.mediator=mediator;??
  • ????}??
  • ??????
  • ????public?abstract?void?method1();?//聲明自身方法,處理自己的行為??
  • ??????
  • ????//定義依賴方法,與中介者進行通信??
  • ????public?void?method2()?{??
  • ????????mediator.operation();??
  • ????}??
  • }??
  • ???????在抽象同事類中聲明了同事類的抽象方法,而在具體同事類中將實現(xiàn)這些方法,典型的具體同事類代碼如下所示:

    [java]?view plaincopy
  • class?ConcreteColleague?extends?Colleague?{??
  • ????public?ConcreteColleague(Mediator?mediator)?{??
  • ????????super(mediator);??
  • ????}??
  • ??????
  • ????//實現(xiàn)自身方法??
  • ????public?void?method1()?{??
  • ????????......??
  • ????}??
  • }??
  • ????? 在具體同事類ConcreteColleague中實現(xiàn)了在抽象同事類中聲明的方法,其中方法method1()是同事類的自身方法(Self-Method),用于處理自己的行為,而方法method2()依賴方法(Depend-Method),用于調(diào)用在中介者中定義的方法,依賴中介者來完成相應(yīng)的行為,例如調(diào)用另一個同事類的相關(guān)方法。

    ?

    ?

    思考

    如何理解同事類中的自身方法與依賴方法?

    20.3 完整解決方案

    ????? 為了協(xié)調(diào)界面組件對象之間的復(fù)雜交互關(guān)系,Sunny公司開發(fā)人員使用中介者模式來設(shè)計客戶信息管理窗口,其結(jié)構(gòu)示意圖如圖20-7所示:

    20-7?引入了中介者類的“客戶信息管理窗口”結(jié)構(gòu)示意圖

    ??????20-7只是一個重構(gòu)之后的結(jié)構(gòu)示意圖,在具體實現(xiàn)時,為了確保系統(tǒng)具有更好的靈活性和可擴展性,我們需要定義抽象中介者和抽象組件類,其中抽象組件類是所有具體組件類的公共父類,完整類圖如圖20-8所示:

    20-8?重構(gòu)后的“客戶信息管理窗口”結(jié)構(gòu)圖

    ????? 在圖20-8中,Component充當(dāng)抽象同事類,Button、List、ComboBoxTextBox充當(dāng)具體同事類,Mediator充當(dāng)抽象中介者類,ConcreteMediator充當(dāng)具體中介者類,ConcreteMediator維持了對具體同事類的引用,為了簡化ConcreteMediator類的代碼,我們在其中只定義了一個Button對象和一個TextBox對象。完整代碼如下所示:

    [java]?view plaincopy
  • //抽象中介者??
  • abstract?class?Mediator?{??
  • ????public?abstract?void?componentChanged(Component?c);??
  • }??
  • ??
  • //具體中介者??
  • class?ConcreteMediator?extends?Mediator?{??
  • ????//維持對各個同事對象的引用??
  • ????public?Button?addButton;??
  • ????public?List?list;??
  • ????public?TextBox?userNameTextBox;??
  • ????public?ComboBox?cb;??
  • ??
  • ????//封裝同事對象之間的交互??
  • ????public?void?componentChanged(Component?c)?{??
  • ????????//單擊按鈕??
  • if(c?==?addButton)?{??
  • ????????????System.out.println("--單擊增加按鈕--");??
  • ????????????list.update();??
  • ????????????cb.update();??
  • ????????????userNameTextBox.update();??
  • ????????}??
  • ????????//從列表框選擇客戶??
  • ????????else?if(c?==?list)?{??
  • ????????????System.out.println("--從列表框選擇客戶--");??
  • ????????????cb.select();??
  • ????????????userNameTextBox.setText();??
  • ????????}??
  • ????????//從組合框選擇客戶??
  • ????????else?if(c?==?cb)?{??
  • ????????????System.out.println("--從組合框選擇客戶--");??
  • ????????????cb.select();??
  • ????????????userNameTextBox.setText();??
  • ????????}??
  • ????}??
  • }??
  • ??
  • //抽象組件類:抽象同事類??
  • abstract?class?Component?{??
  • ????protected?Mediator?mediator;??
  • ??????
  • ????public?void?setMediator(Mediator?mediator)?{??
  • ????????this.mediator?=?mediator;??
  • ????}??
  • ??
  • ????//轉(zhuǎn)發(fā)調(diào)用??
  • ????public?void?changed()?{??
  • ????????mediator.componentChanged(this);??
  • ????}??
  • ??????
  • ????public?abstract?void?update();????
  • }??
  • ??
  • //按鈕類:具體同事類??
  • class?Button?extends?Component?{??
  • ????public?void?update()?{??
  • ????????//按鈕不產(chǎn)生交互??
  • ????}??
  • }??
  • ??
  • //列表框類:具體同事類??
  • class?List?extends?Component?{??
  • ????public?void?update()?{??
  • ????????System.out.println("列表框增加一項:張無忌。");??
  • ????}??
  • ??????
  • ????public?void?select()?{??
  • ????????System.out.println("列表框選中項:小龍女。");??
  • ????}??
  • }??
  • ??
  • //組合框類:具體同事類??
  • class?ComboBox?extends?Component?{??
  • ????public?void?update()?{??
  • ????????System.out.println("組合框增加一項:張無忌。");??
  • ????}??
  • ??????
  • ????public?void?select()?{??
  • ????????System.out.println("組合框選中項:小龍女。");??
  • ????}??
  • }??
  • ??
  • //文本框類:具體同事類??
  • class?TextBox?extends?Component?{??
  • ????public?void?update()?{??
  • ????????System.out.println("客戶信息增加成功后文本框清空。");??
  • ????}??
  • ??????
  • ????public?void?setText()?{??
  • ????????System.out.println("文本框顯示:小龍女。");??
  • ????}??
  • }??
  • ????? 編寫如下客戶端測試代碼:

    [java]?view plaincopy
  • class?Client?{??
  • ????public?static?void?main(String?args[])?{??
  • ????????//定義中介者對象??
  • ????????ConcreteMediator?mediator;??
  • ????????mediator?=?new?ConcreteMediator();??
  • ??????????
  • ????????//定義同事對象??
  • ????????Button?addBT?=?new?Button();??
  • ????????List?list?=?new?List();??
  • ????????ComboBox?cb?=?new?ComboBox();??
  • ????????TextBox?userNameTB?=?new?TextBox();??
  • ??
  • ????????addBT.setMediator(mediator);??
  • ????????list.setMediator(mediator);??
  • ????????cb.setMediator(mediator);??
  • ????????userNameTB.setMediator(mediator);??
  • ??
  • ????????mediator.addButton?=?addBT;??
  • ????????mediator.list?=?list;??
  • ????????mediator.cb?=?cb;??
  • ????????mediator.userNameTextBox?=?userNameTB;??
  • ??????????
  • ????????addBT.changed();??
  • ????????System.out.println("-----------------------------");??
  • ????????list.changed();??
  • ????}??
  • }??
  • ????? 編譯并運行程序,輸出結(jié)果如下:

    --單擊增加按鈕--

    列表框增加一項:張無忌。

    組合框增加一項:張無忌。

    客戶信息增加成功后文本框清空。

    -----------------------------

    --從列表框選擇客戶--

    組合框選中項:小龍女。

    文本框顯示:小龍女。

    20.4?中介者與同事類的擴展

    ?????? Sunny軟件公司CRM系統(tǒng)的客戶對“客戶信息管理窗口”提出了一個修改意見:要求在窗口的下端能夠及時顯示當(dāng)前系統(tǒng)中客戶信息的總數(shù)。修改之后的界面如圖20-9所示:

    20-9?修改之后的“客戶信息管理窗口”界面圖

    ???????從圖20-9中我們不難發(fā)現(xiàn),可以通過增加一個文本標(biāo)簽(Label)來顯示客戶信息總數(shù),而且當(dāng)用戶點擊“增加”按鈕或者“刪除”按鈕時,將改變文本標(biāo)簽的內(nèi)容。

    ????? 由于使用了中介者模式,在原有系統(tǒng)中增加新的組件(即新的同事類)將變得很容易,我們至少有如下兩種解決方案:

    ???????【解決方案一】增加一個界面組件類Label,修改原有的具體中介者類ConcreteMediator,增加一個對Label對象的引用,然后修改componentChanged()方法中其他相關(guān)組件對象的業(yè)務(wù)處理代碼,原有組件類無須任何修改,客戶端代碼也需針對新增組件Label進行適當(dāng)修改。

    ???????【解決方案二】與方案一相同,首先增加一個Label類,但不修改原有具體中介者類ConcreteMediator的代碼,而是增加一個ConcreteMediator的子類SubConcreteMediator來實現(xiàn)對Label對象的引用,然后在新增的中介者類SubConcreteMediator中通過覆蓋componentChanged()方法來實現(xiàn)所有組件(包括新增Label組件)之間的交互,同樣,原有組件類無須做任何修改,客戶端代碼需少許修改。

    ????? 引入Label之后“客戶信息管理窗口”類結(jié)構(gòu)示意圖如圖20-10所示:

    20-10?增加Label組件類后的“客戶信息管理窗口”結(jié)構(gòu)示意圖

    ???????由于【解決方案二】無須修改ConcreteMediator類,更符合“開閉原則”,因此我們選擇該解決方案來對新增Label類進行處理,對應(yīng)的完整類圖如圖20-11所示:

    20-11?修改之后的“客戶信息管理窗口”結(jié)構(gòu)圖

    ????? 在圖20-11中,新增了具體同事類Label和具體中介者類SubConcreteMediator,代碼如下所示:

    [java]?view plaincopy
  • //文本標(biāo)簽類:具體同事類??
  • class?Label?extends?Component?{??
  • ????public?void?update()?{??
  • ????????System.out.println("文本標(biāo)簽內(nèi)容改變,客戶信息總數(shù)加1。");??
  • ????}??
  • }??
  • ??
  • //新增具體中介者類??
  • class?SubConcreteMediator?extends?ConcreteMediator?{??
  • ????//增加對Label對象的引用??
  • ????public?Label?label;??
  • ??????
  • ????public?void?componentChanged(Component?c)?{??
  • ????????//單擊按鈕??
  • if(c?==?addButton)?{??
  • ????????????System.out.println("--單擊增加按鈕--");??
  • ????????????list.update();??
  • ????????????cb.update();??
  • ????????????userNameTextBox.update();??
  • ????????????label.update();?//文本標(biāo)簽更新??
  • ????????}??
  • ????????//從列表框選擇客戶??
  • ????????else?if(c?==?list)?{??
  • ????????????System.out.println("--從列表框選擇客戶--");??
  • ????????????cb.select();??
  • ????????????userNameTextBox.setText();??
  • ????????}??
  • ????????//從組合框選擇客戶??
  • ????????else?if(c?==?cb)?{??
  • ????????????System.out.println("--從組合框選擇客戶--");??
  • ????????????cb.select();??
  • ????????????userNameTextBox.setText();??
  • ????????}??
  • ????}??
  • }??
  • ?????? 修改客戶端測試代碼:

    [java]?view plaincopy
  • class?Client?{??
  • ????public?static?void?main(String?args[])?{??
  • ????????//用新增具體中介者定義中介者對象??
  • ????????SubConcreteMediator?mediator;??
  • ????????mediator?=?new?SubConcreteMediator();??
  • ??????????
  • ????????Button?addBT?=?new?Button();??
  • ????????List?list?=?new?List();??
  • ????????ComboBox?cb?=?new?ComboBox();??
  • ????????TextBox?userNameTB?=?new?TextBox();??
  • ????????Label?label?=?new?Label();??
  • ??
  • ????????addBT.setMediator(mediator);??
  • ????????list.setMediator(mediator);??
  • ????????cb.setMediator(mediator);??
  • ????????userNameTB.setMediator(mediator);??
  • ????????label.setMediator(mediator);??
  • ??????????
  • ????????mediator.addButton?=?addBT;??
  • ????????mediator.list?=?list;??
  • ????????mediator.cb?=?cb;??
  • ????????mediator.userNameTextBox?=?userNameTB;??
  • ????????mediator.label?=?label;??
  • ??????????????
  • ????????addBT.changed();??
  • ????????System.out.println("-----------------------------");??
  • ????????list.changed();??
  • ????}??
  • }??
  • ?????? 編譯并運行程序,輸出結(jié)果如下:

    --單擊增加按鈕--

    列表框增加一項:張無忌。

    組合框增加一項:張無忌。

    客戶信息增加成功后文本框清空。

    文本標(biāo)簽內(nèi)容改變,客戶信息總數(shù)加1。

    -----------------------------

    --從列表框選擇客戶--

    組合框選中項:小龍女。

    文本框顯示:小龍女。

    ???????由于在本實例中不同的組件類(即不同的同事類)所擁有的方法并不完全相同,因此中介者類沒有針對抽象同事類編程,導(dǎo)致在具體中介者類中需要維持對具體同事類的引用,客戶端代碼無法完全透明地對待所有同事類和中介者類。在某些情況下,如果設(shè)計得當(dāng),可以在客戶端透明地對同事類和中介者類編程,這樣系統(tǒng)將具有更好的靈活性和可擴展性。

    思考

    如果不使用中介者模式,按照圖20-3所示設(shè)計方案,增加新組件時原有系統(tǒng)該如何修改?

    ???????在中介者模式的實際使用過程中,如果需要引入新的具體同事類,只需要繼承抽象同事類并實現(xiàn)其中的方法即可,由于具體同事類之間并無直接的引用關(guān)系,因此原有所有同事類無須進行任何修改,它們與新增同事對象之間的交互可以通過修改或者增加具體中介者類來實現(xiàn)如果需要在原有系統(tǒng)中增加新的具體中介者類,只需要繼承抽象中介者類(或已有的具體中介者類)并覆蓋其中定義的方法即可,在新的具體中介者中可以通過不同的方式來處理對象之間的交互,也可以增加對新增同事的引用和調(diào)用。在客戶端中只需要修改少許代碼(如果引入配置文件的話有時可以不修改任何代碼)就可以實現(xiàn)中介者的更換。

    20.4 中介者模式總結(jié)

    ????? 中介者模式將一個網(wǎng)狀的系統(tǒng)結(jié)構(gòu)變成一個以中介者對象為中心的星形結(jié)構(gòu),在這個星型結(jié)構(gòu)中,使用中介者對象與其他對象的一對多關(guān)系來取代原有對象之間的多對多關(guān)系。中介者模式在事件驅(qū)動類軟件中應(yīng)用較為廣泛,特別是基于GUIGraphical User Interface,圖形用戶界面)的應(yīng)用軟件,此外,在類與類之間存在錯綜復(fù)雜的關(guān)聯(lián)關(guān)系的系統(tǒng)中,中介者模式都能得到較好的應(yīng)用。

    ?

    ?????? 1.?主要優(yōu)點

    ?????? 中介者模式的主要優(yōu)點如下:

    ????? ?(1)?中介者模式簡化了對象之間的交互,它用中介者和同事的一對多交互代替了原來同事之間的多對多交互,一對多關(guān)系更容易理解、維護和擴展,將原本難以理解的網(wǎng)狀結(jié)構(gòu)轉(zhuǎn)換成相對簡單的星型結(jié)構(gòu)。

    ????? (2)?中介者模式可將各同事對象解耦。中介者有利于各同事之間的松耦合,我們可以獨立的改變和復(fù)用每一個同事和中介者,增加新的中介者和新的同事類都比較方便,更好地符合“開閉原則”。

    ????? (3)?可以減少子類生成,中介者將原本分布于多個對象間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使各個同事類可被重用,無須對同事類進行擴展。

    ?

    ????? 2.?主要缺點

    ????? 中介者模式的主要缺點如下:

    ????? 在具體中介者類中包含了大量同事之間的交互細節(jié),可能會導(dǎo)致具體中介者類非常復(fù)雜,使得系統(tǒng)難以維護。

    ?

    ????? 3.?適用場景

    ????? 在以下情況下可以考慮使用中介者模式:

    ????? (1)?系統(tǒng)中對象之間存在復(fù)雜的引用關(guān)系,系統(tǒng)結(jié)構(gòu)混亂且難以理解。

    ????? (2)?一個對象由于引用了其他很多對象并且直接和這些對象通信,導(dǎo)致難以復(fù)用該對象。

    ????? (3)?通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類??梢酝ㄟ^引入中介者類來實現(xiàn),在中介者中定義對象交互的公共行為,如果需要改變行為則可以增加新的具體中介者類。

    ?

    練習(xí)

    Sunny軟件公司欲開發(fā)一套圖形界面類庫。該類庫需要包含若干預(yù)定義的窗格(Pane)對象,例如TextPane、ListPane、GraphicPane等,窗格之間不允許直接引用。基于該類庫的應(yīng)用由一個包含一組窗格的窗口(Window)組成,窗口需要協(xié)調(diào)窗格之間的行為。試采用中介者模式設(shè)計該系統(tǒng)。

    ?

    2010年上半年 軟件設(shè)計師 下午試卷 第三題

    ????? 【說明】

    ???????某運輸公司決定為新的售票機開發(fā)車票銷售的控制軟件。圖I給出了售票機的面板示意圖以及相關(guān)的控制部件。

    I?售票機面板示意圖

    ?????? 售票機相關(guān)部件的作用如下所述:

    ?????? (1)?目的地鍵盤用來輸入行程目的地的代碼(例如,200表示總站)。

    ?????? (2)?乘客可以通過車票鍵盤選擇車票種類(單程票、多次往返票和座席種類)。

    ?????? (3)?繼續(xù)/取消鍵盤上的取消按鈕用于取消購票過程,繼續(xù)按鈕允許乘客連續(xù)購買多張票。

    ?????? (4)?顯示屏顯示所有的系統(tǒng)輸出和用戶提示信息。

    ?????? (5)?插卡口接受MCard(現(xiàn)金卡),硬幣口和紙幣槽接受現(xiàn)金。

    ?????? (6)?打印機用于輸出車票。

    ?????? (7)?所有部件均可實現(xiàn)自檢并恢復(fù)到初始狀態(tài)。

    ?????? 現(xiàn)采用面向?qū)ο蠓椒ㄩ_發(fā)該系統(tǒng),使用UML進行建模,系統(tǒng)的頂層用例圖和類圖分別如圖II和圖III所示。

    II 頂層用例

    III?類圖

    【問題1】
    ?????? 根據(jù)說明中的描述,給出圖II中A1和A2所對應(yīng)的執(zhí)行者,U1所對應(yīng)的用例,以及(1)、(2)處所對應(yīng)的關(guān)系。
    【問題2】
    ?????? 根據(jù)說明中的描述,給出圖III中缺少的C1-C4所對應(yīng)的類名以及(3)-(6)處所對應(yīng)的多重度。
    【問題3】

    ?????? 圖III中的類圖設(shè)計采用了中介者(Mediator)設(shè)計模式,請說明該模式的內(nèi)涵。


    總結(jié)

    以上是生活随笔為你收集整理的协调多个对象之间的交互——中介者模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。