設計模式 ( 十五 ) 中介者模式Mediator(對象行為型)

1.概述

在面向對象的軟件設計與開發過程中,根據“單一職責原則”,我們應該盡量將對象細化,使其只負責或呈現單一的職責,即將行為分布到各個對象中。

對于一個模塊或者系統,可能由很多對象構成,而且這些對象之間可能存在相互的引用,在最壞的情況下,每一個對象都知道其他所有的對象,這無疑復雜化了對象之間的聯系。雖然將一個系統分割成許多對象通常可以增強可復用性,但是對象間相互連接的激增又會降低其可復用性,大量的相互連接使得一個對象似乎不太可能在沒有其他對象的支持下工作,系統表現為一個不可分割的整體,而且對系統的行為進行任何較大的改動都會十分困難。結果是你不得不定義大量的子類以定制系統的行為。因此,為了減少對象兩兩之間復雜的引用關系,使之成為一個松耦合的系統,我們需要使用中介者模式.

例子1:

2.問題

面對一系列的相交互對象。怎么樣保證使各對象不需要顯式地相互引用,使其耦合松散?

3.解決方案

中介者模式:用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。中介者模式又稱為調停者模式。(Define an object thatencapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects fromreferring to each other explicitly, and it lets you vary their interaction independently. )

4.適用性

在下列情況下使用中介者模式:

? 1)系統中對象之間存在復雜的引用關系,產生的相互依賴關系結構混亂且難以理解。

? 2)一組對象以定義良好但是復雜的方式進行通信。產生的相互依賴關系結構混亂且難以理解。
? 3)一個對象引用其他很多對象并且直接與這些對象通信 ,導致難以復用該對象。
? 4)想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實現,在中介者中定義對象交互的公共行為,如果需要改變行為則可以增加新的中介者類。

5.結構

1.jpg

6.模式的組成

抽象中介者(Mediator):中介者定義一個接口用于與各同事(Colleague)對象通信。
具體中介者(ConcreteMediator): 具體中介者通過協調各同事對象實現協作行為。了解并維護它的各個同事。
抽象同事類(Colleague class): 定義同事類接口,定義各同事的公有方法.
具體同事類(ConcreteColleague): 實現抽象同事類中的方法。每一個同時類需要知道中介者對象;每個具體同事類只需要了解自己的行為,而不需要了解其他同事類的情況。每一個同事對象在需與其他的同事通信的時候,與它的中介者通信。

7.效果

中介者模式的優點:
1) 減少了子類生成:  Mediator將原本分布于多個對象間的行為集中在一起。改變這些行為只需生成Mediator的子類即可。這樣各個Colleague類可被重用。
2) 簡化各同事類的設計和實現 : 它將各同事類Colleague解耦,Mediator有利于各Colleague間的松耦合. 你可以獨立的改變和復用各Colleague類和Mediator類。
3) 它簡化了對象協議: 用Mediator和各Colleague間的一對多的交互來代替多對多的交互。一對多的關系更易于理解、維護和擴展。
4) 它對對象如何協作進行了抽象 將中介作為一個獨立的概念并將其封裝在一個對象中,使你將注意力從對象各自本身的行為轉移到它們之間的交互上來。這有助于弄清    楚一個系統中的對象是如何交互的。
5) 它使控制集中化 中介者模式將交互的復雜性變為中介者的復雜性。
中介者模式的缺點:
因為中介者封裝了協議,即在具體中介者類中包含了同事之間的交互細節,可能會導致具體中介者類非常復雜,這可能使得中介者自身成為一個難于維護的
龐然大物。

8.實現

<?php  
  
/** 
 * 中介者模式 
 * 
 *  
*/  
/** 
 * 抽象中介者類 
 */  
abstract class Mediator  
{  
    static protected  $_colleaguesend = array(  
                                        'ConcreteColleague1'=> 'ConcreteColleague2',  
                                        'ConcreteColleague2'=> 'ConcreteColleague3',  
                                        'ConcreteColleague3'=> 'ConcreteColleague1',  
                                        );  
    protected  $_colleagues = null; //array  
    public  function register(Colleague $colleague) {  
        $this->_colleagues[get_class($colleague)] = $colleague;  
    }  
  
    public abstract function operation($name, $message);  
}  
/** 
 * 具體中介者類 
 */  
class ConcreteMediator extends Mediator  
{  
      
    public function operation($obj, $message) {  
        $className = self::$_colleaguesend[get_class($obj)];  
        if ($className == get_class($obj) ) {  
            return ;  
        }  
        if ($this->_colleagues[$className]) {  
              
            $this->_colleagues[$className]->notify($message);  
        }     
        return ;  
    }  
}  
/** 
 * 抽象同事類 
 */  
abstract class Colleague  
{  
    protected  $_mediator = null;  
  
    public function __construct($mediator) {  
  
        $this->_mediator = $mediator;  
        $mediator->register($this);  
    }  
    /** 
     * 通過中介實現相互調用 
     */  
    public abstract function send($message);  
    /** 
     * 具體需要實現的業務邏輯代碼 
     */  
    public abstract function notify($message);  
}  
  
/** 
 * 具體同事類 
 */  
class ConcreteColleague1 extends Colleague  
{  
    public function __construct(Mediator $mediator) {  
        parent::__construct($mediator);  
    }  
  
    public function send($message) {  
        $this->_mediator->operation($this, $message);  
    }  
      
    public function notify($message) {  
        echo 'ConcreteColleague1 m:', $message, '<br/>';  
    }  
  
}  
  
/** 
 * 具體同事類 
 */  
class ConcreteColleague2 extends Colleague  
{  
    public function __construct(Mediator $mediator) {  
        parent::__construct($mediator);  
    }  
  
    public function send($message) {  
        $this->_mediator->operation($this, $message);  
    }  
    public function notify($message) {  
        echo 'ConcreteColleague2 m:', $message, '<br/>';  
    }  
      
}  
  
  
/** 
 * 具體同事類 
 */  
class ConcreteColleague3 extends Colleague  
{  
    public function __construct(Mediator $mediator) {  
        parent::__construct($mediator);  
    }  
  
    public function send($message) {  
        $this->_mediator->operation($this, $message);  
    }  
    public function notify($message) {  
        echo 'ConcreteColleague3 m:', $message, '<br/>';  
    }  
      
}  
$objMediator = new  ConcreteMediator();  
$objC1 = new ConcreteColleague1($objMediator);  
$objC2 = new ConcreteColleague2($objMediator);  
$objC3 = new ConcreteColleague3($objMediator);  
  
$objC1->send("from ConcreteColleague1");  
$objC2->send("from ConcreteColleague2");  
$objC3->send("from ConcreteColleague3");  
/****************************************************/

9.與其他相關模式

1)外觀模式,Facade與中介者的不同之處在于它是對一個對象子系統進行抽象,從而提供了一個為方便的接口。它的協議是單向的,即 Facade對象對這個子系統類提出請求,但反之則不。相反,Mediator提供了各Colleague對象不支持或不能支持的協作行為,而且協議是多向。
2) Colleague可使用Observers模式與Mediator通信。

10.總結與分析

1)迪米特法則的一個典型應用:在中介者模式中,通過創造出一個中介者對象,將系統中有關的對象所引用的其他對象數目減少到最少,使得一個對象與其同事之間的相互作用被這個對象與中介者對象之間的相互作用所取代。因此,中介者模式就是迪米特法則的一個典型應用。
2) 通過引入中介者對象,可以將系統的網狀結構變成以中介者為中心的星形結構,中介者承擔了中轉作用和協調作用。中介者類是中介者模式的核心,它對整個系統進行控制和協調,簡化了對象之間的交互,還可以對對象間的交互進行進一步的控制。
3) 中介者模式的主要優點在于簡化了對象之間的交互,將各同事解耦,還可以減少子類生成,對于復雜的對象之間的交互,通過引入中介者,可以簡化各同事類的設計和實現;中介者模式主要缺點在于具體中介者類中包含了同事之間的交互細節,可能會導致具體中介者類非常復雜,使得系統難以維護。
4) 中介者模式適用情況包括:系統中對象之間存在復雜的引用關系,產生的相互依賴關系結構混亂且難以理解;一個對象由于引用了其他很多對象并且直接和這些對象通信,導致難以復用該對象;想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類

轉自:http://blog.csdn.net/hguisu/article/details/7554612

原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2908

(0)
s19930811s19930811
上一篇 2015-07-20 22:55
下一篇 2015-07-20 23:00

相關推薦

  • 第四周博客作業

    1、復制/etc/skel目錄為/home/tuser1,要求/home/tuser1及其內部文件的屬組和其它用戶均沒有任何訪問權限。 [root@localhost ~]# cp -r /etc/skel /home/tuser1 [root@localhost ~]# ls …

    Linux干貨 2016-12-28
  • 高級文件系統管理

    高級文件系統管理 本章內容 ? 設定文件系統配額 ? 設定和管理軟RAID設備 ? 配置邏輯卷 ? 設定LVM快照 ? btrfs文件系統 配置配額系統 ?綜述 ? 在內核中執行 ? 以文件系統為單位啟用 ? 對不同組或者用戶的策略不同    &nb…

    Linux干貨 2016-09-01
  • LVS的詳細應用

    LVS是Linux Virtual Server的簡寫, 意思是Linux虛擬服務器, 是一個虛擬的服務器集群系統. LVS的宗旨:    1. 使用集群技術和Linux操作系統實現一個高性能, 高可用的服務器;    2. 很好的可伸縮性(Scalability);    3. 很好的可靠性(Re…

    Linux干貨 2016-12-05
  • N21-天天-第八周課程練習

    1、請描述網橋、集線器、二層交換機、三層交換機、路由器的功能、使用場景與區別。 主要功能: 網橋將兩個相似的網絡連接起來,并對網絡數據的流通進行管理。它工作于數據鏈路層,不但能擴展網絡的距離或范圍,而且可提高網絡的性能、可靠性和安全性。 集線器的英文稱為“Hub”。主要功能是對接收到的信號進行再生整形放大,以擴大網絡的傳輸距離,同時把所有節點集中在以它為中心…

    Linux干貨 2016-08-29
  • Linux破解root口令

    Centos5、6版本破解口令方法 1 啟動系統 2 在操作系統選擇菜單界面選中要啟動的內核 — 按a鍵 3 在行尾輸入 1(或s或S或single)— 按回車鍵 4 使用passwd命令修改口令即可   Centos7版本破解口令方法 方法1 1 啟動系統 2 在操作系統選擇菜單界面選中要啟動的內核 — 按e鍵…

    Linux干貨 2018-01-08
  • 文件查找與壓縮-2

    1、tar [OPTION]… (1) 創建歸檔(打包而非壓縮) 其中-c是創建備份,-f是指定創建備份成的文件即是/PATH/TO/SOMEFILE.tar #tar -c -f /PATH/TO/SOMEFILE.tar  FILE… #tar cf / PATH/TO/SOMEFILE.tar FILE… …

    Linux干貨 2016-08-18
欧美性久久久久