1. 程式人生 > >23、行為型-中介者模式(Mediator)

23、行為型-中介者模式(Mediator)

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

中介者模式包含如下幾個角色:

● Mediator(抽象中介者):它定義一個介面,該介面用於與各同事物件之間進行通訊。
● ConcreteMediator(具體中介者):它是抽象中介者的子類,通過協調各個同事物件來實現協作行為,它維持了對各個同事物件的引用。
● Colleague(抽象同事類):它定義各個同事類公有的方法,並聲明瞭一些抽象方法來供子類實現,同時它維持了一個對抽象中介者類的引用,其子類可以通過該引用來與中介者通訊。
● ConcreteColleague(具體同事類):它是抽象同事類的子類;每一個同事物件在需要和其他同事物件通訊時,先與中介者通訊,通過中介者來間接完成與其他同事類的通訊;在具體同事類中實現了在抽象同事類中宣告的抽象方法

1、主要優點

(1) 中介者模式簡化了物件之間的互動,它用中介者和同事的一對多互動代替了原來同事之間的多對多互動,一對多關係更容易理解、維護和擴充套件,將原本難以理解的網狀結構轉換成相對簡單的星型結構。
(2) 中介者模式可將各同事物件解耦。中介者有利於各同事之間的鬆耦合,我們可以獨立的改變和複用每一個同事和中介者,增加新的中介者和新的同事類都比較方便,更好地符合“開閉原則”。
(3) 可以減少子類生成,中介者將原本分佈於多個物件間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使各個同事類可被重用,無須對同事類進行擴充套件。

2、主要缺點

在具體中介者類中包含了大量同事之間的互動細節,可能會導致具體中介者類非常複雜,使得系統難以維護。

3、適用場景

(1) 系統中物件之間存在複雜的引用關係,系統結構混亂且難以理解。
(2) 一個物件由於引用了其他很多物件並且直接和這些物件通訊,導致難以複用該物件。
(3) 想通過一箇中間類來封裝多個類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實現,在中介者中定義物件互動的公共行為,如果需要改變行為則可以增加新的具體中介者類。

我們就以租房為例,中介機構充當租房者與房屋所有者之間的中介者

輸入圖片說明

/**
 * 2018/12/6
 * 抽象中介者
 *
 * @author machuanpeng
 */ 
public abstract class Mediator {
    //申明一個聯絡方法
    public abstract void constact(String message,Person person);
}
/**
 * 2018/12/6
 * 抽象同事物件
 *
 * @author machuanpeng
 */
public abstract class Person {
    
    protected String name;
    protected Mediator mediator;
    
    Person() {}
    
    Person(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
    
    /**與中介者聯絡*/
    public void constact(String message){
        mediator.constact(message, this);
    }

    /**獲取資訊*/
    public void getMessage(String message);
    
    public void getName() {
        return this.name;
	}
    
    public void setName(String name) {
        this.name = name;
	}
    
    public void getMediator() {
        return this.mediator;
	}
    
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
	}
}
/**
 * 2018/12/6
 * 房主
 *
 * @author machuanpeng
 */
public class HouseOwner extends Person{

    HouseOwner(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void getMessage(String message){
        System.out.println("房主:" + name +",獲得資訊:" + message);
    }
}
/**
 * 2018/12/6
 * 租客
 *
 * @author machuanpeng
 */
public class Renter extends Person{

    Renter(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void getMessage(String message){
        System.out.println("租客:" + name +",獲得資訊:" + message);
    }
}
/**
 * 2018/12/6
 * 具體中介者物件
 *
 * @author machuanpeng
 */
public class MediatorStructure extends Mediator{
    //首先中介結構必須知道所有房主和租房者的資訊
    private HouseOwner houseOwner;
    private Renter renter;
    
    public void constact(String message, Person person) {
        if(person == houseOwner){ 
            //如果是房主,則租房者獲得資訊
            renter.getMessage(message);
        }else{ 
            //反正則是房主獲得資訊
            houseOwner.getMessage(message);
        }
    }

    public HouseOwner getHouseOwner() {
        return houseOwner;
    }

    public void setHouseOwner(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }

    public Renter getRenter() {
        return renter;
    }

    public void setRenter(Renter renter) {
        this.renter = renter;
    }
}

測試:

public class Client {
    public static void main(String[] args) {
        //一個房主、一個租房者、一箇中介機構
        MediatorStructure mediator = new MediatorStructure();
        
        //房主和租房者只需要知道中介機構即可
        HouseOwner houseOwner = new HouseOwner("張三", mediator);
        Renter renter = new Renter("李四", mediator);
        
        //中介結構要知道房主和租房者
        mediator.setHouseOwner(houseOwner);
        mediator.setRenter(renter);
        
        renter.constact("聽說你那裡有三室的房主出租.....");
        houseOwner.constact("是的!請問你需要租嗎?"