〇、小故事
小王大学毕业了,打算来北京闯荡一下,于是就先寄宿到了他的表姐家,白天的时候,自己在外面小区转一转,看看能不能找到可以租到的房子,他找了好几天都没有找到合适的,要么就是小区里一张租房子的广告都没有,好不容易找到几个,里面的房间大小和价格又不合适。北京实在是太大了,而且这边人生地不熟的,找房子真的是耗费了他大量的力气。
到了周末,表姐问他这几天都在干嘛,他告诉了表姐自己找房子的经历,表姐跟他说,明天姐带你去找中介,这个事儿好办。第二天,小王和表姐到了某中介公司,跟中介表明自己需要寻找什么样的房子——主卧还是次卧
、屋子面积多少平米
、是否向阳
、房子在哪个区域内
、押金是多少
…… 根据这些条件,中介给小王列出了好几个房源,然后就带着他们去看房,很快小王就找到了自己心仪的房子了。
那么,上面的故事也是很多北漂人比较熟悉的经历吧。那么,对于房东和租客来说,中介人员就属于一个中间层,房东们与中介联系,将自己待出租的房子录入中介系统中,而访客又会通过中介去找房子,对于房子信息的采集,归类,降价,涨价,下架,匹配……这一系列工作都由中介人员去做,这样既使得房东很轻松,不用一次次对接房客,一遍遍的介绍自己的房子;也使得房客很轻松,直接通过中介系统就可以过滤出符合自己的房子,然后直奔目标,不用像个无头苍蝇一般的在各个小区乱碰运气的找房子。那么这个就是我们今天要介绍的设计模式——中介者模式。
一、模式定义
中介者模式(Mediator Pattern
)
使用中介者模式来集中相关对象之间复杂的沟通和控制方式。
为了便于理解,我们再举一个系统设计上的例子。在网上售卖商城的系统中,存在三个功能,分别为采购功能、销售功能和库存功能。
【采购功能】需要从销售功能获取到销售情况,并且确定是否要继续采购增加库存量。
【销售功能】要获得库存信息,并且销售量大于库存量,则需要通知采购功能快速采购商品。并且每当销售了产品后,需要扣减库存。
【库存功能】如果库存压力大了,要提示销售功能去折价促销,尽快消耗库存,并且通知采购功能暂时不要进行该商品的采购行为。
通过上面的描述,我们应该可以看到,采购
、销售
和库存
这三个业务域是互相依赖的,如下图所示:
那么如果依照这种关联关系进行开发的话,就会出现这三个功能相互耦合的情况。如果需求变更了,会产生牵一发而动全身的情况发生。无形之中增加了业务开发量。那么针对这种情况,我们可以采取中介者模式或者叫做调停者模式。如下所示:
根据最小知识原则,无论是采购、销售还是库存,在他们眼中,最亲密的朋友都是这个中介者。而中介者将所有的业务逻辑关系进行整合,只需要这三个业务域提供针对他们自己业务的操作接口接口,后续如果需求变更,大概率涉及到修改的也都是在中介者。
二、模式类图
针对上面讲的网上售卖商城例子,我们来画一下类的关系图。首先,创建3个类分别为Purchase(采购人员
)、Sale(销售人员
)和Stock(库存人员
),其次,创建一个抽象的同事类
AbstractColleague,让刚刚创建的这3种人员都继承这个抽象类,该抽象类没有抽象方法需要子类实现,只是禁止本类被实例化成对象。在该抽象类中,引用了一个中介者类
Mediator,该类引用了Purchase、Sale和Stock这三种工作人员,并且把他们的调用逻辑抽取出来放到中介者类中。请见下图所示:
三、代码实现
创建抽象同事类,并引用中介者Mediator的实例对象:AbstractColleague.java
public abstract class AbstractColleague { protected Mediator mediator; public AbstractColleague(Mediator mediator) { this.mediator = mediator; } }
创建采购人员:Purchase.java
public class Purchase extends AbstractColleague { public Purchase(Mediator mediator) { super(mediator); } /** 采购电脑 */ public void buyComputer(int num) { System.out.println(); super.mediator.purchaseByComputer(num); } /** 不再采购电脑 */ public void refuseBuyComputer() { System.out.println("不再采购电脑!"); } }
创建销售人员:Sale.java
public class Sale extends AbstractColleague { public Sale(Mediator mediator) { super(mediator); } /** 销售电脑 */ public void sellComputer(int number) { super.mediator.saleSellComputer(number); System.out.println("销售电脑" + number + "台"); } /** 获得销售情况(即:售卖了多少台电脑) */ public int getSaleStatus() { // 模拟销售数量 int sellNumber = new Random(System.currentTimeMillis()).nextInt(100); System.out.println("电脑的销售情况为:" + sellNumber + "台"); return sellNumber; } /** 折价处理 */ public void offSale() { super.mediator.saleOffSale(); } }
创建库存人员:Stock.java
public class Stock extends AbstractColleague { private static int COMPUTER_NUM = 100; public Stock(Mediator mediator) { super(mediator); } /** 增加库存 */ public void increaseComputer(int number) { COMPUTER_NUM += number; System.out.println("电脑的库存数量为:" + COMPUTER_NUM); } /** 减少库存 */ public void decreaseComputer(int number) { COMPUTER_NUM -= number; System.out.println("电脑的库存数量为:" + COMPUTER_NUM); } /** 获得当前库存 */ public int getStockNumber() { return COMPUTER_NUM; } /** 清理库存 */ public void clearStock() { System.out.println("清理库存数量为:" + COMPUTER_NUM); super.mediator.stockClear(); } }
创建中介者:Mediator.java
public class Mediator { protected Purchase purchase; // 采购人员 protected Sale sale; // 销售人员 protected Stock stock; // 库存人员 public Mediator() { purchase = new Purchase(this); sale = new Sale(this); stock = new Stock(this); } /** 采购电脑 */ public void purchaseByComputer(int num) { int saleStatus = sale.getSaleStatus(); // 如果销售情况不好(即:没有超过80台),则采购总数减半 String msg = ""; if (saleStatus <= 80) { num = num / 2; msg = "由于销售不佳,采购总数减半,"; } System.out.println(msg + "原有库存电脑" + stock.getStockNumber() + "台,现采购电脑" + num + "台"); stock.increaseComputer(num); } /** 销售电脑 */ public void saleSellComputer(int num) { // 如果库存数量不足,则采购2倍的num电脑数,暂时只售卖库存中有的数量 int stockNum; if ((stockNum = stock.getStockNumber()) < num) { purchase.buyComputer(2*num); num = stockNum; } stock.decreaseComputer(num); } /** 折价销售电脑 */ public void saleOffSale() { System.out.println("折价销售电脑"); } /** 清理库存 */ public void stockClear() { sale.offSale(); // 折价销售电脑 purchase.refuseBuyComputer(); // 不要采购电脑 } }
创建测试类:MediatorTest.java
public class MediatorTest { public static void main(String[] args) { Mediator mediator = new Mediator(); System.out.println("--------采购人员采购电脑--------"); Purchase purchase = new Purchase(mediator); purchase.buyComputer(100); System.out.println("--------销售人员销售电脑--------"); Sale sale = new Sale(mediator); sale.sellComputer(1); System.out.println("--------库房人员清库处理--------"); Stock stock = new Stock(mediator); stock.clearStock(); } }
执行结果:
--------采购人员采购电脑-------- 电脑的销售情况为:36台 由于销售不佳,采购总数减半,原有库存电脑100台,现采购电脑50台 电脑的库存数量为:150 --------销售人员销售电脑-------- 电脑的库存数量为:149 销售电脑1台 --------库房人员清库处理-------- 清理库存数量为:149 折价销售电脑 不再采购电脑! Process finished with exit code 0
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」