用一个对象封装一系列的对象交互,中介者使对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变他们之间的独立。
个人理解
当多个对象之间存在着过多的耦合时,可以通过中介者模式进行解耦,将具体的对象之间的耦合转为中介者与具体对象的耦合,假如说之前是三个对象的相互之间的耦合,转为中介者与具体类的耦合之后,从耦合性上大大的降低了,这样如果再来对其进行修改的话,那么变更部分主要在中介者部分,从而使得该结构更加稳定。
角色分析
中介者角色分以下几个部分:
1. Mediator抽象中介者角色:抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
2. Concrete Mediator具体中介者角色:具体中介者角色通过协调各同事角色实现写作行为,依赖于各同事角色。
3. Colleague同事角色:每个同事类的任务中,包括自身需要完成的功能,以及自己完不成要交给中介者进行其余处理的部分功能。
案例解析
案例一:购销系统应用中介者模式
案例背景介绍
由公司购销系统来讲,购入商品的时候,库存需要相应的增加,此处属于依赖其他对象的关系。需要清仓的时候,一方面,需要停止进货,打折促销完成清仓任务。从这几部来看实体类(Purchase、Sale、Store)三者之间如果不采用中介者模式的时候,需要在完成购入的任务时,使得Purchase类依赖Store类。在完成清仓并促销等任务时,使得Store中依赖Purchase类和Sale类。这样的依赖关系就显得过于复杂,而且不容易管理。
使用中介者模式之后,就会使得三者之间的依赖关系纯粹而简单,只与中介者类耦合,其余的操作也可以在中介者类中进行完成。这样既方便管理与维护,也降低了耦合度提高了稳定性。
主要代码
相当于同事角色抽象类。定义公共的属性和制定构造方法。
public abstract class AbstractEmployee { protected AbstractMediator mediator; public AbstractEmployee(){} public AbstractEmployee(AbstractMediator mediator) { this.mediator = mediator; } }
具体同事角色实现类
public class PurchaseMan extends AbstractEmployee { public PurchaseMan(){ } public PurchaseMan(AbstractMediator mediator) { super(mediator); } public void buy(int i) { this.mediator.executor("buy", i); } public void stopBuy() { System.out.println("停止购买"); } }
public class SaleMan extends AbstractEmployee { public SaleMan(){} public SaleMan(AbstractMediator mediator) { super(mediator); } public int getStatus() { Random random = new Random(); int num = random.nextInt(120); return num; } public void sale(Integer num) { this.mediator.executor("sale", num); } }
public class StoreMan extends AbstractEmployee { private int num = 100; public StoreMan() { } public StoreMan(AbstractMediator mediator) { super(mediator); } public void increaseStore(Integer num) { this.num += num; } public Integer getNum() { return this.num; } public void clearStore() { this.mediator.executor("sell", this.num); } public void decreaseStore(Integer num2) { this.num -= num2; } }
中介者角色抽象类:抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
public abstract class AbstractMediator { protected static PurchaseMan purchase = new PurchaseMan(); protected static SaleMan sale = new SaleMan(); protected static StoreMan store = new StoreMan(); public abstract void executor(String exeStr, Object...obj); }
Concrete Mediator具体中介者角色:具体中介者角色通过协调各同事角色实现写作行为,依赖于各同事角色。
public class Mediator extends AbstractMediator { @Override public void executor(String exeStr, Object... obj) { // 购入 if("buy".equals(exeStr)) { this.buySomething((Integer)obj[0]); } // 卖出 else if("sell".equals(exeStr)) { this.sellSomething((Integer)obj[0]); } // 清仓 else if("clear".equals(exeStr)) { this.clear(); } // 打折促销 else if("sale".equals(exeStr)) { this.sale((Integer)obj[0]); } } private void sale(int num) { System.out.println("便宜卖出" + num); } private void clear() { System.out.println("clear --- start"); if(store.getNum() > 0) { System.out.println("清仓>>" + store.getNum()); purchase.stopBuy(); sale.sale(store.getNum()); store.decreaseStore(store.getNum()); } else { System.out.println("已经清仓"); } System.out.println("clear --- stop"); } private void sellSomething(Integer num) { System.out.println("sell ---- start"); if(store.getNum() <= num) { System.out.println("买入" + (num - store.getNum())); System.out.println("清仓"); purchase.buy(num - store.getNum()); store.clearStore(); } else { System.out.println("卖出" + num); store.decreaseStore(num); } System.out.println("sell ---- end"); } private void buySomething(Integer num) { System.out.println("buy ---- start"); if(sale.getStatus() > 100) { System.out.println("购入" + num); store.increaseStore(num); } else{ System.out.println("购入" + num / 3); store.increaseStore(num / 3); } System.out.println("buy ---- end"); } }
测试类
public class MainTest { public static void main(String[] args) { Mediator mediator = new Mediator(); PurchaseMan purchase = new PurchaseMan(mediator); purchase.buy(100); SaleMan sale = new SaleMan(mediator); sale.sale(100); StoreMan store = new StoreMan(mediator); store.clearStore(); } }
案例二:模拟飞机场调度
案例背景
飞机场作为各个飞机落地时的中介是非常重要的,如果当前跑道上有飞机在降落,那么达到的其他的飞机不能进行降落,得等待该飞机完成降落后,刚到达的飞机才能进行安全的降落。本例通过多线程的方式进行中介者模式的运用。模拟飞机的降落过程。
主要代码
相当于同事类的抽象类。定义了中介者以及 必要的一些飞机落地的方法。
public abstract class Airplane { protected static AriportMediator mediator = new AriportMediator(); /** * 准备降落 */ public abstract void prepareLanded(); /** * 检查是否安全 */ public abstract boolean checkIsSafe(); /** * 着陆 */ public abstract void landing(); /** * 继续飞行,直到确认安全为止 */ public abstract void continueToFly(); public void landingMethod(){ this.prepareLanded(); if(this.checkIsSafe()){ landing(); }else{ continueToFly(); } } }
public class CNAirPlane extends Airplane{ @Override public void prepareLanded() { System.out.println("CNAirPlane--准备着陆!"); this.mediator.setAirPlaneWaitingLoading(this); } @Override public synchronized boolean checkIsSafe() { return this.mediator.checkIsSafe(); } @Override public synchronized void landing() { this.mediator.setStatus(0); System.out.println("CNAirPlane--正在着陆!"); try { new Thread().sleep(2000); } catch (Exception e) { e.printStackTrace(); } this.mediator.removeAirplane(this); System.out.println("CNAirPlane--着陆完成!"); this.mediator.setStatus(1); } @Override public void continueToFly() { System.out.println("CNAirPlane--继续飞行!"); while(true){ if(this.mediator.checkIsSafe()){ landing(); break; } } } }
public class CNSHAirPlane extends Airplane{ @Override public void prepareLanded() { System.out.println("CNSHAirPlane--准备着陆!"); this.mediator.setAirPlaneWaitingLoading(this); } @Override public boolean checkIsSafe() { return this.mediator.checkIsSafe(); } @Override public synchronized void landing() { System.out.println("CNSHAirPlane--正在着陆!"); try { new Thread().sleep(1000); } catch (Exception e) { e.printStackTrace(); } this.mediator.setStatus(0); this.mediator.removeAirplane(this); System.out.println("CNSHAirPlane--着陆完成!"); } @Override public void continueToFly() { System.out.println("CNSHAirPlane--继续飞行!"); while(true){ if(this.mediator.checkIsSafe()){ landing(); break; } } } }
中介者角色,完成多个飞机角色的交互,协调之间的降落关系,使得飞机可以安全的落地。
public class AriportMediator { // 记录飞机申请着陆的序列 private static List<Object> airPlaneWaitingLoading = new ArrayList<Object>(); // 飞机着陆状态0:表示不可以着陆,1表示可以着陆。 private static int airPlaneLoadingStatus = 1; public static List<Object> getAirPlaneWaitingLoading() { return airPlaneWaitingLoading; } public static synchronized void setAirPlaneWaitingLoading(Object airPlane) { airPlaneWaitingLoading.add(airPlane); // System.out.println(airPlaneWaitingLoading); } public static synchronized void removeAirplane(Object airPlane) { airPlaneWaitingLoading.remove(airPlane); // System.out.println(airPlaneWaitingLoading); } public synchronized boolean checkIsSafe() { // 正在准备着陆的飞机 if(airPlaneWaitingLoading != null && airPlaneWaitingLoading.size() > 1 || airPlaneLoadingStatus == 0){ return false; } else{ return true; } } public synchronized void setStatus(int status){ airPlaneLoadingStatus = status; // System.out.println("状态:" + airPlaneLoadingStatus); } public int getStatus(){ return airPlaneLoadingStatus; } }
测试类
public class MainTest { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { Airplane airPlane = new CNAirPlane(); airPlane.landingMethod(); } }).start(); new Thread(new Runnable() { @Override public void run() { Airplane airPlane2 = new CNSHAirPlane(); airPlane2.landingMethod(); } }).start(); } }
中介者模式优点
减少类之间的依赖关系,把原来的一对多的依赖关系变成一对一的依赖关系,减少了依赖降低了耦合度,提高了稳定性。
中介者模式缺点
导致中介者类膨胀,逻辑过于复杂化,同事类越多,那么中介者中逻辑越复杂。
设计模式代码下载