中介設計模式(Mediator Design Pattern)定義了一個單獨的(中介)物件,來封裝一組物件之間的互動。
如果物件之間存在大量的相互關聯和呼叫,若有一個物件發生變化,則需要跟蹤和該物件的其他所有物件,並進行適當處理。
而中介模式將這些物件之間的互動委派給中介物件互動,來避免物件之間直接互動,使其耦合鬆散。
首先,定義一個抽象中介者介面,該介面用於與各物件之間進行通訊。其程式碼範例如下:
public abstract class Mediator {
// 維持所有同事物件的參照
protected ArrayList<Colleague> colleagues;
// 註冊方法,用於增加同事物件
public void register(Colleague colleague) {
colleagues.add(colleague);
}
// 宣告抽象的業務方法
public abstract void operation();
}
對於具體的中介者物件,主要是實現自己的業務方法,封裝同事之間的呼叫。其程式碼範例如下:
public class ConcreteMediator extends Mediator {
@Override
public void operation() {
// 通過中介者呼叫同事類的方法
this.colleagues.get(0).method1();
}
}
然後,需要定義一個抽象的同事類,其維持了一個抽象中介者的參照,用於呼叫中介者的方法。其程式碼範例如下:
public abstract class Colleague {
// 維持一個抽象中介者的參照
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
// 宣告自身方法,處理自己的行為
public abstract void method1();
// 定義依賴方法,與中介者通訊
public void method2() {
mediator.operation();
}
}
具體的同事類也比較簡單,只需要繼承自抽象同事類,然後定義好自己的行為即可。
中介模式的主要優點如下:
中介模式的主要缺點如下:
中介模式的適用場景如下:
在 JDK 中 java.util.Timer
就使用到了中介模式。如下是其原始碼部分:
public class Timer {
private final TaskQueue queue = new TaskQueue();
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
if (Math.abs(period) > (Long.MAX_VALUE >> 1))
period >>= 1;
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
if (task.state != TimerTask.VIRGIN)
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.SCHEDULED;
}
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}
}