魔鬼还是天使的博客

魔鬼还是天使的博客

「补课」进行时:设计模式(7)——租房子中的中介者模式-LMLPHP

1. 前文汇总

「补课」进行时:设计模式系列

2. 租房子

国内某知名大学著名毕业生隔壁老王同学在近日毕业了,好不容易在大魔都找到一份工作,接下来就需要做另一件大事儿了,租房子。

租过房子的同学应该都知道,最方便最快捷的方式就是找房租中介,如果不找中介的话,就需要自己去联系一个一个的房东,去约看每一间的房子。

如果恰巧这些房东之间有联系,都在出租房屋,当客户 A 看了一号房东的房子,感觉不满意,一号房东推荐它可以去看看其他几个房东的房子,这时候,这个房东就需要联系他的其他几个房东朋友。

如果这些房东中间恰好有一个人把房子租出来,他就需要自己通知所有的朋友,他的房子租掉了(状态变了)。

「补课」进行时:设计模式(7)——租房子中的中介者模式-LMLPHP

这里就造成了一个问题,当其中一个人发生了变化,需要告诉其他几个人,牵一发而动全身。

这种情况下,如果能加入一个中介,将会大大的改善这种情况。

「补课」进行时:设计模式(7)——租房子中的中介者模式-LMLPHP

这时,如果一个人的状态变化了,只需要通知中介就行,有任何问题直接找中介进行处理,不再会有刚才的牵一发而动全身的情况出现。

接下来看下示例代码:

2.1 抽象中介类

public abstract class Mediator {
    public abstract void Common(String type);
}

这里定义了一个同事类之间交互方法。

2.2 抽象房东类

public abstract class Colleague {
    public abstract void showHouse();
}

这里定义一个抽象方法,抽象每个房东都需要做的事情(展示自己的房屋)。

2.3 具体房东类

public class SmallHouseColleague extends Colleague {
    @Override
    public void showHouse() {
        System.out.println("一室一厅便宜整洁");
    }
}

public class TwoHouseColleague extends Colleague {
    @Override
    public void showHouse() {
        System.out.println("两居室——合适靠谱");
    }
}

public class ThreeHouseColleague extends Colleague {
    @Override
    public void showHouse() {
        System.out.println("三居室——大气宽松");
    }
}

这里定义了三个具体的房东要做的事情(展示自己的房子)。

2.4 具体房屋中介

public class HouseMediator extends Mediator {
    private SmallHouseColleague smallHouse;
    private TwoHouseColleague twoHouse;
    private ThreeHouseColleague threeHouse;

    public void setSmallHouse(SmallHouseColleague smallHouse) {
        this.smallHouse = smallHouse;
    }

    public void setTwoHouse(TwoHouseColleague twoHouse) {
        this.twoHouse = twoHouse;
    }

    public void setThreeHouse(ThreeHouseColleague threeHouse) {
        this.threeHouse = threeHouse;
    }

    @Override
    public void Common(String type) {
        switch (type) {
            case "单间":
                smallHouse.showHouse();
                System.out.println("如果可以就可以租房了!");
                break;
            case "两居室":
                twoHouse.showHouse();
                System.out.println("如果可以就可以租房了!");
                break;
            case "三居室":
                threeHouse.showHouse();
                System.out.println("如果可以就可以租房了!");
                break;
            default:
                System.out.println(type + "暂时没有房源!");
                break;
        }
    }
}

2.5 测试类

public class Test {
    public static void main(String[] args) {
        System.out.println("租客来看房啦!!!");
        //初始化中介
        HouseMediator mediator = new HouseMediator();
        //初始化房屋信息
        SmallHouseColleague smallHouseColleague = new SmallHouseColleague( );
        TwoHouseColleague twoHouseColleague = new TwoHouseColleague( );
        ThreeHouseColleague threeHouseColleague = new ThreeHouseColleague( );

        //中介获取房屋信息
        mediator.setSmallHouse(smallHouseColleague);
        mediator.setTwoHouse(twoHouseColleague);
        mediator.setThreeHouse(threeHouseColleague);

        // 租户A需要两居室、提供看房
        mediator.Common("两居室");

        // 租户B需要四居室、暂无房源
        mediator.Common("四居室");
    }
}

最后的执行结果如下:

租客来看房啦!!!
两居室——合适靠谱
如果可以就可以租房了!
四居室暂时没有房源!

3. 中介者模式

3.1 定义

中介者模式的定义为:Define an object that encapsulates how a set ofobjects interact.Mediator promotes loose coupling by keeping objects fromreferring to each other explicitly,and it lets you vary their interactionindependently.(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。)

3.2 通用类图

「补课」进行时:设计模式(7)——租房子中的中介者模式-LMLPHP

从类图中看,中介者模式由以下几部分组成:

  • Mediator: 抽象中介者角色,定义统一的接口,用于各同事角色之间的通信。
  • Concrete Mediator: 具体中介者角色,通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
  • Colleague: 同事角色,每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。

3.3 通用抽象中介者

public abstract class Mediator {
    // 定义同事类
    protected ConcreteColleague1 colleague1;
    protected ConcreteColleague2 colleague2;

    // 通过 get/set 将同事注入进来
    public ConcreteColleague1 getC1() {
        return colleague1;
    }

    public void setC1(ConcreteColleague1 colleague1) {
        this.colleague1 = colleague1;
    }

    public ConcreteColleague2 getC2() {
        return colleague2;
    }

    public void setC2(ConcreteColleague2 colleague2) {
        this.colleague2 = colleague2;
    }

    // 中介者模式的业务逻辑
    public abstract void doSomething1();
    public abstract void doSomething2();
}

3.4 通用中介者

public class ConcreteMediator extends Mediator {
    @Override
    public void doSomething1() {
        // 调用同事类的方法
        super.colleague1.selfMethod1();
        super.colleague2.selfMethod2();
    }

    @Override
    public void doSomething2() {
        super.colleague1.selfMethod1();
        super.colleague2.selfMethod2();
    }
}

3.5 抽象同事类

public abstract class Colleague {
    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
}

3.6 具体同事类

public class ConcreteColleague1 extends Colleague{

    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    public void selfMethod1() {
        // 处理自己的业务逻辑
    }

    public void depMethod1() {
        // 处理自己的业务逻辑
        // 自己处理不了的业务委托中介者进行处理
        super.mediator.doSomething1();
    }
}

public class ConcreteColleague2 extends Colleague {

    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    public void selfMethod2() {
        // 处理自己的业务逻辑
    }

    public void depMethod2() {
        // 处理自己的业务逻辑
        // 自己处理不了的业务委托中介者进行处理
        super.mediator.doSomething2();
    }
}

4. 中介者模式的优缺点

4.1 优点

中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合。

4.2 缺点

中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。

11-04 12:19