中介模式(Mediator)
中介者模式是一种行为设计模式,能减少对象之间混乱无序的依赖关系。
该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作(中转与协调)。
优点:
缺点:
这里举一个车辆呼叫的例子。
组件接口
public interface Component {
/**
* 设置中介者引用
*/
void setMediator(Mediator mediator);
Type getType();
}
组件实现
/**
* 组件之一:用户
*/
public class ComponentUser implements Component{
// 中介者引用
private Mediator mediator;
// 现金
private int money;
public ComponentUser(int money) {
this.money = money;
}
// 设置中介者引用
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public Type getType() {
return Type.USER;
}
public int getMoney() {
return money;
}
// 叫车
public String callTheCar(Type type){
return mediator.callTheCar(type);
}
// 扣费 并返回余额
public int deduct(int money){
this.money -= money;
return money;
}
}
/**
* 组件之一:小车
*/
public class ComponentCar implements Component {
// ... 省略成员变量 mediator 和 money
// ... 省略成员方法 setMediator 和 getType 和 getMoney
// 收费 并返回余额
public void charge() {
mediator.charge(1);
money += 1;
}
}
/**
* 组件之一:货车
*/
public class ComponentVan implements Component {
// ... 省略成员变量 mediator 和 money
// ... 省略成员方法 setMediator 和 getType 和 getMoney
// 收费 并返回余额
public void charge() {
mediator.charge(2);
money += 2;
}
}
/**
* 组件之一:货车
*/
public class ComponentTruck implements Component {
// ... 省略成员变量 mediator 和 money
// ... 省略成员方法 setMediator 和 getType 和 getMoney
// 收费 并返回余额
public void charge() {
mediator.charge(3);
money += 3;
}
}
类型枚举
public enum Type {
// 用户、小车、面包车、货车
USER,CAR,VAN,TRUCK;
}
中介者接口
public interface Mediator {
/**
* 把组件 注册到 中介者
*/
void registerComponent(Component component);
// 呼叫车辆
String callTheCar(Type type);
// 收费
void charge(int i);
}
中介者实现:车辆呼叫中心
public class MediatorCenter implements Mediator {
// 保存其下所有组件的引用
private ComponentUser user;
private ComponentCar car;
private ComponentVan van;
private ComponentTruck truck;
// 注册组件
@Override
public void registerComponent(Component component) {
switch (component.getType()) {
case USER:
user = (ComponentUser) component;
break;
case CAR:
car = (ComponentCar) component;
break;
case VAN:
van = (ComponentVan) component;
break;
case TRUCK:
truck = (ComponentTruck) component;
break;
default:
}
}
// 呼叫车辆
@Override
public String callTheCar(Type type) {
switch (type) {
case CAR:
if (car != null) {
car.charge();
return "呼叫小车成功";
}
case VAN:
if (van != null) {
van.charge();
return "呼叫面包车成功";
}
case TRUCK:
if (truck != null) {
truck.charge();
return "呼叫货车成功";
}
default:
return "暂无车辆可调度";
}
}
// 付费方法
@Override
public void charge(int paymentAmount) {
user.deduct(paymentAmount);
}
// 获取余额
public int getMoneyByType(Type type){
switch (type) {
case USER:
return user.getMoney();
case CAR:
return car.getMoney();
case VAN:
return van.getMoney();
case TRUCK:
return truck.getMoney();
default:
return 999;
}
}
}
测试代码
public class MediatorTest {
@Test
public void test() {
// 创建中介者
Mediator mediatorCenter = new MediatorCenter();
// 创建组件
ComponentUser componentUser = new ComponentUser(10);
ComponentCar componentCar = new ComponentCar();
ComponentVan componentVan = new ComponentVan();
ComponentTruck componentTruck = new ComponentTruck();
// 设置中介引用
componentUser.setMediator(mediatorCenter);
componentCar.setMediator(mediatorCenter);
componentVan.setMediator(mediatorCenter);
componentTruck.setMediator(mediatorCenter);
// 把组件注册进中介者
mediatorCenter.registerComponent(componentUser);
mediatorCenter.registerComponent(componentCar);
mediatorCenter.registerComponent(componentVan);
Assertions.assertEquals("呼叫小车成功", mediatorCenter.callTheCar(Type.CAR));
Assertions.assertEquals("暂无车辆可调度", mediatorCenter.callTheCar(Type.TRUCK));
Assertions.assertEquals("呼叫小车成功", mediatorCenter.callTheCar(Type.CAR));
Assertions.assertEquals("呼叫面包车成功", mediatorCenter.callTheCar(Type.VAN));
mediatorCenter.registerComponent(componentTruck);
Assertions.assertEquals("呼叫货车成功", mediatorCenter.callTheCar(Type.TRUCK));
Assertions.assertEquals(3, componentUser.getMoney());
Assertions.assertEquals(2, componentCar.getMoney());
Assertions.assertEquals(2, componentVan.getMoney());
Assertions.assertEquals(3, componentTruck.getMoney());
}
}
public class Timer {
private final TaskQueue queue = new TaskQueue();
private final TimerThread thread = new TimerThread(queue);
public void schedule(TimerTask task, long delay) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
sched(task, System.currentTimeMillis()+delay, 0);
}
public void schedule(TimerTask task, Date time) {
sched(task, time.getTime(), 0);
}
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
// Constrain value of period sufficiently to prevent numeric
// overflow while still being effectively infinitely large.
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();
}
}
public void cancel() {
synchronized(queue) {
thread.newTasksMayBeScheduled = false;
queue.clear();
queue.notify(); // In case queue was already empty.
}
}
// ... 忽略
}
Timer 是中介者,TimerTask 是抽象组件类,
我们只要实现 TimerTask,再使用 schedule 方法注册进中介者即可实现定时器功能。
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
以上代码与文章会同步到 github 仓库:
/chenbihao/Design-Patterns