"围观"设计模式(25)--行为型之中介者模式(Mediator Pattern)

用一个对象封装一系列的对象交互,中介者使对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变他们之间的独立。


个人理解

当多个对象之间存在着过多的耦合时,可以通过中介者模式进行解耦,将具体的对象之间的耦合转为中介者与具体对象的耦合,假如说之前是三个对象的相互之间的耦合,转为中介者与具体类的耦合之后,从耦合性上大大的降低了,这样如果再来对其进行修改的话,那么变更部分主要在中介者部分,从而使得该结构更加稳定。


角色分析

中介者角色分以下几个部分:

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();
		
	}
}


中介者模式优点

减少类之间的依赖关系,把原来的一对多的依赖关系变成一对一的依赖关系,减少了依赖降低了耦合度,提高了稳定性。


中介者模式缺点

导致中介者类膨胀,逻辑过于复杂化,同事类越多,那么中介者中逻辑越复杂。


设计模式代码下载

设计模式源码下载




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值