折騰Java設計模式之中介者模式

博文原址:折騰Java設計模式之中介者模式html

中介者模式

中介者模式(Mediator Pattern)是用來下降多個對象和類之間的通訊複雜性。這種模式提供了一箇中介類,該類一般處理不一樣類之間的通訊,並支持鬆耦合,使代碼易於維護。中介者模式屬於行爲型模式。java

通俗點來說就是提供一箇中介平臺,說到平臺,那其實很容易聯繫到咱們很熟悉的房地產中介。咱們能夠直接經過這個平臺獲得咱們想要的信息,不用對象自身與其餘對象交互。git

買房子租房子就不須要去找房東,只須要在中介那裏獲取相應的房產信息。以下圖那樣,兩方只須要找中介便可。github

房地產中介

再來看一張對比圖。設計模式

中介者先後對比

有沒有感受沒有使用以前,對象間互相依賴互相調用,錯綜複雜,盤根錯節,當加入中介者後,對象間的關係一目瞭然,清晰明瞭。由中介對象來封裝一系列對象之間的交互關係。中介者使各個對象之間不須要顯式地相互引用,從而使耦合性下降,並且能夠獨立地改變它們之間的交互行爲。微信

中介者模式UML圖

UML類圖和時序圖

類圖和時序圖

collague1和collague2類不直接相互依賴,它們是用起控制和協調交互做用的公共中介接口(mediate()方法),這使它們有獨立交互的執行方式。mediate1類實現collague1和collague2之間的依賴。ide

中介者模式角色

角色

抽象中介者(Mediator): 定義了同事對象到中介者對象之間的接口。ui

具體中介者(ConcreteMediator): 實現抽象中介者的方法,它須要知道全部的具體同事類,同時須要從具體的同事類那裏接收信息,而且向具體的同事類發送信息。this

抽象同事類(Colleague): 定義了中介者對象的接口,它只知道中介者而不知道其餘的同事對象。spa

具體同事類(ConcreteColleague) : 每一個具體同事類都只須要知道本身的行爲便可,可是他們都須要認識中介者。

示例代碼

源碼地址

抽象中介者

@Slf4j
public abstract class Mediator {

    /** * 房東map */
    protected Map<People, Message> landlordMap = Maps.newHashMap();

    /** * 租戶列表 */
    protected List<People> renterList = Lists.newArrayList();

    /** * 註冊房東信息 * * @param landlord 房東 * @param message 房屋信息 */
    public void registerLandlord(People landlord, Message message) {
        landlordMap.put(landlord, message);
        log.info("中介信息:房東|{}|加入到中介平臺,房屋信息:{}", landlord.getName(), message);
    }

    /** * 變動房東信息 * * @param landlord 房東 * @param message 房屋信息 */
    protected void modifyLandlordInfo(People landlord, Message message) {
        landlordMap.put(landlord, message);
        log.info("中介信息:房東|{}|修改他在中介平臺的房屋信息,現房屋信息:{}", landlord.getName(), message);
    }

    /** * 註冊租戶信息 * * @param renter 租戶 */
    public void registerRenter(People renter) {
        renterList.add(renter);
        log.info("中介信息:租戶|{}|來中介平臺租房", renter.getName());
    }


    /** * 聲明抽象方法 由具體中介者子類實現 消息的中轉和協調 */
    public abstract void operation(People people, Message message);

}
複製代碼

抽象同事類

@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class People {

    private Mediator mediator;

    private String name;

    /** * 向中介發送消息 */
    protected abstract void sendMessage(Message message);

    /** * 從中介獲取消息 */
    protected abstract void getMessage(Message message);
}
複製代碼

具體同事類 房東和租戶

@Slf4j
public class Landlord extends People {

    public Landlord(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    protected void sendMessage(Message message) {
        getMediator().operation(this, message);
    }

    @Override
    protected void getMessage(Message message) {
        log.info("房東|{}|從中介獲取到租戶的信息:{}", getName(), message);
    }
}
複製代碼
@Slf4j
public class Renter extends People {

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

    @Override
    protected void sendMessage(Message message) {
        getMediator().operation(this, message);
    }

    @Override
    protected void getMessage(Message message) {
        log.info("租戶|{}|從中介獲取到房東的信息:{}", getName(), message);
    }
}
複製代碼

具體中介者

public class RealEstateAgent extends Mediator {

    @Override
    public void operation(People people, Message message) {
        if (people instanceof Renter) {
            // 將租戶的租房條件信息發送給房東們
            landlordMap.keySet().forEach(landlord -> landlord.getMessage(message));

            // 租戶收到中介那裏房東的房屋信息
            landlordMap.values().forEach(messages -> people.getMessage(messages));
        } else if (people instanceof Landlord) {
            // 將房東的房屋信息發送給租戶們
            renterList.forEach(renter -> renter.getMessage(message));
            // 變動中介裏的房東房屋信息
            modifyLandlordInfo(people, message);
        }
    }
}
複製代碼

客戶端

@Slf4j
public class Client {

    public static void main(String[] args) {
        Mediator mediator = new RealEstateAgent();
        People laoWang = new Landlord(mediator, "老王");
        People laoLee = new Landlord(mediator, "老李");
        People laoBai = new Landlord(mediator, "老白");

        People xiaoSan = new Renter(mediator, "小3");
        People xiaoWang = new Renter(mediator, "小王");

        mediator.registerLandlord(laoWang, Message.builder().msg("我這有2500的房子,市中心").build());
        mediator.registerLandlord(laoBai, Message.builder().msg("我這有2000的房子,地鐵旁").build());
        mediator.registerLandlord(laoLee, Message.builder().msg("我這有2000的房子,落地陽臺,大空間,採光好,地鐵旁").build());

        mediator.registerRenter(xiaoSan);

        log.info("小3開始找房子");
        xiaoSan.sendMessage(Message.builder().msg("想找個月租2000塊的房子,靠近地鐵").build());
        log.info("沒過多久---------老白升級了房屋信息");
        laoBai.sendMessage(Message.builder().msg("我這有2000的房子,地鐵旁,我又加了空調和熱水器").build());
        mediator.registerRenter(xiaoWang);
        log.info("小王開始找房子");
        xiaoWang.sendMessage(Message.builder().msg("想找個月租2500塊的房子,靠近地鐵").build());
        log.info("沒過多久---------老李也升級了房屋信息");
        laoBai.sendMessage(Message.builder().msg("我這有2000的房子,落地陽臺,大空間,採光好,地鐵旁,我也加了空調和熱水器").build());

    }
}
複製代碼

最終出效果的以下

效果

如今我來分析下里面各個角色的做用:

首先先分析兩個抽象類。抽象同事類,含有名稱和中介者的引用,有2個方法從中介拿信息和發信息給中介。抽象中介者,其中含有房東的map信息,key爲房東數據,value爲房東的房屋信息,用來房東註冊和房東房屋信息變動;租戶的列表信息,供租戶註冊,同時還有個協調方法,用於協調房東和租戶。

具體抽象類(房地產中介),實現了抽象中介者的協調方法,當租戶發送消息時,將租戶的租房條件信息發送給全部房東們同時該租戶收到中介那裏全部房東的房屋信息;當房東發送消息時,將房東的房屋信息發送給全部租戶們同時變動中介裏的改房東房屋信息。

具體同事實現類(房東和租戶),實現了抽象同事類的讀取消息方法和發送消息方法(該房屋就是依靠中介者的協調方法來實現)。

JDK中的應用

經過使用一箇中間對象來進行消息分發以及減小類之間的直接依賴。

java.util.Timer

java.util.concurrent.Executor#execute()

java.util.concurrent.ExecutorService#submit()

java.lang.reflect.Method#invoke()

總結

優勢

使用中介者模式能夠把對個同事對象之間的交互封裝到中介者對象裏面,從而使得同事對象之間鬆散耦合。 中介者模式能夠將原先多對多的同事對象關係變成中介者對象一對多同事對象的關係,這樣會讓對象之間的關係更容易理解和實現。 同事對象之間的交互都被封裝到中介者對象裏面集中管理,集中了控制交互。當交互發生改變時,着重修改的是中介者對象。當須要擴展中介者對象時,其餘同事對象不須要作修改。

缺點

若是同事對象多了,交互也複雜了。中介者會龐大,變得複雜難以維護。

參考

中介者模式|菜鳥教程

Mediator pattern

細數JDK裏的設計模式

JAVA設計模式之 中介者模式【Mediator Pattern】

歡迎關注

微信公衆號
相關文章
相關標籤/搜索