1. 程式人生 > >設計模式之中介者模式(Mediator Pattern)

設計模式之中介者模式(Mediator Pattern)

  • 中介者模式定義
    Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. 用一箇中介物件封裝一系列的物件互動,中介者使各個物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立的改變他們之間的互動。

  • 中介者模式通用類圖
    在這裡插入圖片描述


    從以上類圖可以看到,中介者模式主要有三個角色:

    • 抽象中介者:抽象中介者角色定義統一的介面,用於各個同事之間的通訊。
    • 中介者實現類:從抽象中介者繼承而來,實現抽象中介者中定義的事件方法。從一個同事類接收訊息,然後通過訊息影響其他同時類。
    • 同事類:如果一個物件會影響其他的物件,同時也會被其他物件影響,那麼這兩個物件稱為同事類。在類圖中,同事類只有一個,這其實是現實的省略,在實際應用中,同事類一般由多個組成,他們之間相互影響,相互依賴。同事類越多,關係越複雜。並且,同事類也可以表現為繼承了同一個抽象類的一組實現組成。在中介者模式中,同事類之間必須通過中介者才能進行訊息傳遞。
  • 中介者模式通用程式碼
    抽象中介者Mediator

public abstract class Mediator {

	protected ConcreteColleague1 c1;
	protected ConcreteColleague2 c2;
	
	public ConcreteColleague1 getC1() {
		return c1;
	}
	public void setC1(ConcreteColleague1 c1) {
		this.c1 = c1;
	}
	public ConcreteColleague2 getC2() {
		return c2;
	}
	public void setC2(ConcreteColleague2 c2) {
		this.c2 = c2;
	}
	
	public abstract void doSth1();
	public abstract void doSth2();
}

抽象同事類Colleague

public abstract class Colleague {

	protected Mediator mediator;

	public Colleague(Mediator _mediator) {
		this.mediator = _mediator;
	}
}

具體中介者

public class ConcreteMediator extends Mediator{

	@Override
	public void doSth1() {
		super.c1.selfMethod1();
		super.c2.selfMethod2();
	}

	@Override
	public void doSth2() {
		super.c1.selfMethod1();
		super.c2.selfMethod2();
	}
}

具體同事類

public class ConcreteColleague1 extends Colleague {

	public ConcreteColleague1(Mediator _mediator) {
		super(_mediator);
	}

	public void selfMethod1() {
		//TODO
	}

	public void depMethod1() {
		super.mediator.doSth1();
	}
}
public class ConcreteColleague2 extends Colleague {

	public ConcreteColleague2(Mediator _mediator) {
		super(_mediator);
	}

	public void selfMethod2() {
		// TODO
	}

	public void depMethod2() {
		super.mediator.doSth2();
	}
}
  • 中介者模式例項類圖
    相比有很多男生都喜歡金庸的武俠小說吧,筆者也不例外。江湖中門派眾多,總會有一些小嘍囉偷學少林絕學去做一些見不得人的勾當。前段時間武當派和峨眉派的的弟子被大力金剛指所殺,大力金剛指是少林派的絕學,自古有天下武功出少林的沒說,大家自然也不敢輕舉妄動。這個時候大家推舉出了德高望重的武林盟主,作為江湖的中間人,一旦有什麼不和諧的地方,由武林盟主出面進行溝通,其實這個例子就符合中介者模式。

在這裡插入圖片描述

  • 中介者模式例項程式碼
    抽象中介者類
public abstract class WulinAlliance {

	abstract void notice(String message, United united);
}

抽象同事類

public abstract class United {

	protected WulinAlliance wulinAlliance;

	public United(WulinAlliance wulinAlliance) {
		this.wulinAlliance = wulinAlliance;
	}
}

具體同事類

public class Wudang extends United {
	public Wudang(WulinAlliance wulinAlliance) {
		super(wulinAlliance);
	}

	public void sendAlliance(String message) {
		wulinAlliance.notice(message, this);
	}

	public void getNotice(String message) {
		System.out.println("武當收到訊息:" + message);
	}
}
public class Shaolin extends United {
	public Shaolin(WulinAlliance wulinAlliance) {
		super(wulinAlliance);
	}

	public void sendAlliance(String message) {
		wulinAlliance.notice(message, Shaolin.this);
	}

	public void getNotice(String message) {
		System.out.println("少林收到訊息:" + message);
	}
}
public class Emei extends United {
    public Emei(WulinAlliance wulinAlliance) {
        super(wulinAlliance);
    }
    public void sendAlliance(String message) {
        wulinAlliance.notice(message, Emei.this);
    }
    public void getNotice(String message) {
        System.out.println("峨眉收到訊息:" + message);
    }
}

具體中介者類

public class Champions extends WulinAlliance {
	private Wudang wudang;
	private Shaolin shaolin;
	private Emei emei;

	public void setWudang(Wudang wudang) {
		this.wudang = wudang;
	}

	public void setEmei(Emei emei) {
		this.emei = emei;
	}

	public void setShaolin(Shaolin shaolin) {
		this.shaolin = shaolin;
	}

	@Override
	public void notice(String message, United united) {
		if (united == wudang) {
			shaolin.getNotice(message);
		} else if (united == emei) {
			shaolin.getNotice(message);
		} else if (united == shaolin) {
			wudang.getNotice(message);
			emei.getNotice(message);
		}
	}
}

客戶端呼叫

public class Client {
	public static void main(String[] args) {
		Champions champions = new Champions();
		Wudang wudang = new Wudang(champions);
		Shaolin shaolin = new Shaolin(champions);
		Emei emei = new Emei(champions);
		champions.setWudang(wudang);
		champions.setShaolin(shaolin);
		champions.setEmei(emei);
		wudang.sendAlliance("武當弟子被少林大力金剛指所殺");
		emei.sendAlliance("峨眉弟子被少林大力金剛指所殺");
		shaolin.sendAlliance("少林弟子絕不會做出這種事情");
	}
}

輸出結果:

少林收到訊息:武當弟子被少林大力金剛指所殺
少林收到訊息:峨眉弟子被少林大力金剛指所殺
武當收到訊息:少林弟子絕不會做出這種事情
峨眉收到訊息:少林弟子絕不會做出這種事情
  • 中介者模式的優點
    • 符合迪米特原則,將原有的一對多的依賴變成了一對一的依賴,降低類間的耦合。
    • 使用中介者模式可以將物件的行為和協作進行抽象,能夠比較靈活的處理物件間的相互作用。
  • 中介者模式的適用場景
    • 系統中物件之間存在比較複雜的引用關係,導致他們之間的依賴關係結構混亂而且難以複用該物件。
    • 想通過一箇中間類來封裝多個類中的行為,而又不想生成太多的子類。

參考書籍:設計模式之禪
例項程式碼放在這裡