設計模式之中介者模式

0x01.定義與類型

  • 定義:定義一箇中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合鬆散,且能夠獨立地改變它們之間的交互。中介者模式又叫調停模式,它是迪米特法則的典型應用。
  • 經過使對象明確地相互引用來促進鬆散耦合,並容許獨立地改變它們的交互。
  • 類型:行爲型
  • 模式簡單實現
/**
 * 同事抽象類
 */
public abstract class Colleague {

    //中介者抽象類
    protected Mediator mediator;

    //接受消息
    public abstract void receive();

    //發送消息
    public abstract void send();

    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }
}

/**
 * 中介者抽象類
 */
public abstract class Mediator {

    //註冊同事
    abstract void register(Colleague colleague);

    //通知中介者,發送消息
    abstract void relay(Colleague colleague);

}

/***
 * 中介者實現類
 */
public class ConcreteMediator implements Mediator {

    /**
     * 被中介者代理的同事
     */
    private List<Colleague> colleagues;

    public ConcreteMediator() {
        colleagues = new ArrayList<>();
    }

    public void register(Colleague colleague) {
        if (!colleagues.contains(colleague)) {
            colleague.setMediator(this);
            this.colleagues.add(colleague);
        }
    }

    public void relay(Colleague colleague) {
        colleagues.forEach(c -> {
            if (!c.equals(colleague)) {
                c.receive();
            }
        });
    }
}

/**
 * 具體的同事類1
 */
public class ConcreteColleague1 extends Colleague {
    @Override
    public void receive() {
        System.out.println("colleague1 receive message.");
    }

    @Override
    public void send() {
        System.out.println("colleague1 send message.");
        //請中介者轉發
        this.mediator.relay(this);
    }
}

/**
 * 具體的同事類2
 */
public class ConcreteColleague2 extends Colleague {
    @Override
    public void receive() {
        System.out.println("colleague2 receive message.");
    }

    @Override
    public void send() {
        System.out.println("colleague2 send message.");
        //請中介者轉發
        this.mediator.relay(this);
    }
}
  • 測試與應用
/**
 * 測試與應用
 */
public class Test {

    public static void main(String[] args) {
        //構建中介者
        Mediator mediator = new ConcreteMediator();

        //構建具體的同事類
        Colleague colleague1 = new ConcreteColleague1();
        Colleague colleague2 = new ConcreteColleague2();

        //註冊同事
        mediator.register(colleague1);
        mediator.register(colleague2);

        //發送消息
        colleague1.send();
        colleague2.send();
    }
}
  • 輸入結果
colleague1 send message.
colleague2 receive message.
colleague2 send message.
colleague1 receive message.
  • 樣例代碼UML類圖

mediator1.png

  • 中介者模式角色介紹html

    • 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象註冊與轉發同事對象信息的抽象方法。
    • 具體中介者(ConcreteMediator)角色:實現中介者接口,定義一個 List 來管理同事對象,協調各個同事角色之間的交互關係,所以它依賴於同事角色。
    • 抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現全部相互影響的同事類的公共功能。
    • 具體同事類(Concrete Colleague)角色:是抽象同事類的實現者,當須要與其餘同事對象交互時,由中介者對象負責後續的交互。

0x02.適用場景

  • 系統中對象之間存在複雜的引用關係,產生的相互依賴關係結構混亂且難以理解。
  • 交互的公共行爲,若是須要改變行爲則能夠增長新的中介者類

0x03.優缺點

1.優勢

  • 下降了對象之間的耦合性,使得對象易於獨立地被複用。
  • 將對象間的一對多關聯轉變爲一對一的關聯,提升系統的靈活性,使得系統易於維護和擴展。

2.缺點

  • 中介者過多,致使系統複雜

0x04.中介模式簡單樣例

  • 學習羣組的互相通知,消息的發送由中介者去統一管理
/**
 * 中介者類
 */
public class StudyGroup {

    //發送消息
    public static void showMessage (User user, String message) {
        System.out.println(new Date().toString() + " [" + user.getName() + "] :" + message);
    }
}

/**
 * 一塊兒學習的同窗
 */
public class User {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User (String name) {
        this.name = name;
    }

    public void sendMessage (String message) {
        StudyGroup.showMessage(this, message);
    }
}
  • 測試與應用類
/**
 * 測試與應用
 */
public class Test {

    public static void main(String[] args) {
        User ko = new User("K.O");
        User tom = new User("Tom");
        ko.sendMessage("learn design pattern.");
        tom.sendMessage("ok!");
    }
}
  • 輸入結果
Sat Nov 16 17:49:06 CST 2019 [K.O] :learn design pattern.
Sat Nov 16 17:49:06 CST 2019 [Tom] :ok!

0x05.相關設計模式

  • 中介者模式和觀察者模式java

    • 中介者進行通信

0x06.源碼中的中介者模式

  • Timer#schedule

0x07.代碼地址

0x08.推薦閱讀

相關文章
相關標籤/搜索