趣解设计模式之《为什么租房子要找中介?》

〇、小故事

小王大学毕业了,打算来北京闯荡一下,于是就先寄宿到了他的表姐家,白天的时候,自己在外面小区转一转,看看能不能找到可以租到的房子 ,他找了好几天都没有找到合适的,要么就是小区里一张租房子的广告都没有,好不容易找到几个,里面的房间大小和价格又不合适。北京实在是太大了,而且这边人生地不熟的,找房子真的是耗费了他大量的力气。

到了周末,表姐问他这几天都在干嘛,他告诉了表姐自己找房子的经历,表姐跟他说,明天姐带你去找中介,这个事儿好办 。第二天,小王和表姐到了某中介公司,跟中介表明自己需要寻找什么样的房子------主卧还是次卧屋子面积多少平米是否向阳房子在哪个区域内押金是多少...... 根据这些条件,中介给小王列出了好几个房源,然后就带着他们去看房,很快小王就找到了自己心仪的房子了

那么,上面的故事也是很多北漂人比较熟悉的经历吧。那么,对于房东和租客来说,中介人员就属于一个中间层,房东们与中介联系,将自己待出租的房子录入中介系统中,而访客又会通过中介去找房子,对于房子信息的采集,归类,降价,涨价,下架,匹配......这一系列工作都由中介人员去做,这样既使得房东很轻松,不用一次次对接房客,一遍遍的介绍自己的房子;也使得房客很轻松,直接通过中介系统就可以过滤出符合自己的房子,然后直奔目标,不用像个无头苍蝇一般的在各个小区乱碰运气的找房子 。那么这个就是我们今天要介绍的设计模式------中介者模式

一、模式定义

中介者模式Mediator Pattern

使用中介者模式来集中相关对象之间复杂的沟通和控制方式。

为了便于理解,我们再举一个系统设计上的例子。在网上售卖商城的系统中,存在三个功能,分别为采购功能销售功能库存功能

采购功能 】需要从销售功能获取到销售情况,并且确定是否要继续采购增加库存量。

销售功能 】要获得库存信息,并且销售量大于库存量,则需要通知采购功能快速采购商品。并且每当销售了产品后,需要扣减库存。

库存功能】如果库存压力大了,要提示销售功能去折价促销,尽快消耗库存,并且通知采购功能暂时不要进行该商品的采购行为。

通过上面的描述,我们应该可以看到,采购销售库存这三个业务域是互相依赖的,如下图所示:

那么如果依照这种关联关系进行开发的话,就会出现这三个功能相互耦合的情况。如果需求变更了,会产生牵一发而动全身的情况发生。无形之中增加了业务开发量。那么针对这种情况,我们可以采取中介者模式或者叫做调停者模式。如下所示:

根据最小知识原则,无论是采购、销售还是库存,在他们眼中,最亲密的朋友都是这个中介者。而中介者将所有的业务逻辑关系进行整合,只需要这三个业务域提供针对他们自己业务的操作接口接口,后续如果需求变更,大概率涉及到修改的也都是在中介者

二、模式类图

针对上面讲的网上售卖商城例子,我们来画一下类的关系图。首先,创建3个类分别为Purchase采购人员)、Sale销售人员)和Stock库存人员),其次,创建一个抽象的同事类AbstractColleague ,让刚刚创建的这3种人员都继承这个抽象类,该抽象类没有抽象方法需要子类实现,只是禁止本类被实例化成对象。在该抽象类中,引用了一个中介者类Mediator,该类引用了Purchase、Sale和Stock这三种工作人员,并且把他们的调用逻辑抽取出来放到中介者类中。请见下图所示:

三、代码实现

创建抽象同事类,并引用中介者Mediator的实例对象AbstractColleague.java

java 复制代码
public abstract class AbstractColleague {
    protected Mediator mediator;
    public AbstractColleague(Mediator mediator) {
        this.mediator = mediator;
    }
}

创建采购人员Purchase.java

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

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

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

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

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

执行结果

java 复制代码
--------采购人员采购电脑--------

电脑的销售情况为:36台
由于销售不佳,采购总数减半,原有库存电脑100台,现采购电脑50台
电脑的库存数量为:150
--------销售人员销售电脑--------
电脑的库存数量为:149
销售电脑1台
--------库房人员清库处理--------
清理库存数量为:149
折价销售电脑
不再采购电脑!

Process finished with exit code 0

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
yuuki2332339 小时前
【C语言】文件操作(附源码与图片)
c语言·后端
IT_陈寒9 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
DIY机器人工房9 小时前
【嵌入式面试题】STM32F103C8T6 完整元器件解析 + 面试问题答案
stm32·单片机·面试·嵌入式·面试题·diy机器人工房
无名之辈J10 小时前
系统崩溃(OOM)
后端
晴殇i10 小时前
前端鉴权新时代:告别 localStorage,拥抱更安全的 JWT 存储方案
前端·javascript·面试
来旺10 小时前
互联网大厂Java面试全解析及三轮问答专项
java·数据库·spring boot·安全·缓存·微服务·面试
码农刚子10 小时前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
间彧10 小时前
Java ConcurrentHashMap如何合理指定初始容量
后端
catchadmin10 小时前
PHP8.5 的新 URI 扩展
开发语言·后端·php
小奋斗10 小时前
面试官:[1] == '1'和[1] == 1结果是什么?
前端·面试