中介者模式(调停者模式)

中介者模式(调停者模式)

通过一个问题引入:进销存管理

有3个模块,采购管理、销售管理、存货管理。

采购管理:根据销售状况进行采购(依赖销售管理);采购时考虑库存容量,修改库存(依赖存货管理)

销售管理:销售时,会修改库存的值(依赖存货管理),如果库存不够,需要通知采购管理模块进行采购(依赖销售管理)

存货管理:库存数量过多时,如果销售状况不佳(依赖销售管理),则降低采购数量(依赖采购管理)

画个类图:

                                                 

可以看到,这三个类的耦合度很高,而且关系很复杂,在样的情况下,如果要进行修改或者改进,风险是很高的,那怎么降低类之间的耦合呢?想象一下网络拓扑结构中的星型结构,计算机间交流的时候,通过交换机进行交流,而不是计算机之间直接相连。如果直接相连,想要进行扩展的时候,比如说要加一台计算机,就需要连接很多的线,但是,使用交换机的情况下只需要把新来的计算机连接到交换机上就可以,至于交换机怎么把消息发给其他计算机,不归计算机管,计算机要做的就是发送数据给交换机,从交换机取数据。

有了交换机的例子,把上面的进销存管理的问题也加上一个“交换机”(中介者),这样,每一个类只依赖中介者,通过中介者,来完成对其它类依赖的逻辑。

                                                                             

中介者模式的定义

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

                                            

  • Mediator : 抽象中介者角色,定义了类之间(同事角色之间)交互的方法。
  • Concrete : 具体中介者角色,实现了类之间(同事劫色之间)交互的方法。
  • Colleague : 同事角色,每一个同事角色都与中介者关联,通过中介者关联其他的同事角色,与其他同事角色交互时,通过中介者进行交互。同事角色拥有的方法:1.同事本身的行为,不涉及交互,例如修改自己的一个字段,这样的行为叫做自发行为,与中介者没有任何的依赖;2.依赖中介者与其它同事角色进行交互,必须依赖中介者才能完成,叫做依赖方法。

通用的中介者模式的代码:

public abstract class Mediator {
    //定义同事类
    protected ConcreteColleague1 c1;
    protected ConcreteColleague2 c2;

    //通过setter方法,注入同事类
    public void setC1(ConcreteColleague1 c){
        this.c1 = c;
    }

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

    //依赖处理的方法
    public abstract Object doSometing();
}

使用具体的同事类,而不是抽象的同事类的原因:在实际开发的过程中,两个同事类可能不会有完全相同的方法,中介者处理交互时,调用的同事角色的方法不一定是共有的,所以很难抽象出一个符合所有同事类的接口

public ConcreteMediator extends Mediator {
    @Override
    public void doSometing(){
        super.c1.selfMethod();
        super.c2.selfMethod();
    }   
}

中介者进行交互时,可以调用同事类的自发行为,来完成对象之间的交互;同事角色进行交互时,只需要调用终结者的方法即可

public abstract class Colleague {
    protected Mediator mediator;
    public Colleague(Mediator _mediator){
        this.mediator = _mediator;
    }
}

抽象的同事类,这个类的作用就是关联中介者

public ConcreteColleague1 extends Colleague{
    public ConcreteColleague1(Mediator _mediator){
        super(_mediator);
    }
    //自发行为,没有任何依赖
    public Object selfMethod(){

    }

    //依赖方法,委托给中介者
    public Object depMethod(){
        super.mediator.doSomething();
    }
}


public ConcreteColleague2 extends Colleague{
    public ConcreteColleague2(Mediator _mediator){
        super(_mediator);
    }

    public Object selfMethod(){

    }

    public Object depMethod(){
        super.mediator.doSomething();
    }
}

具体的同事类,有两种方法:自发行为,与其他同事类或中介者没有任何关联;依赖方法,与其他的同事类进行交互时,将具体的实现委托给中介者(中介者模式,使用了代理模式,这是个人的一些理解,关于这一点,一会再讨论)

既然使用了中介者模式,同事角色之间一定会有交互,所以一定会有中介者,所以具体同时角色使用构造方法注入的方式。

总结

中介者模式的优点

减少类之间的依赖,从一对多(多个同事角色)的关系变为一对一(一个中介者);减少了依赖,同时降低了耦合度。

中介者模式的缺点

“庞大”的中介者,同事类增多的时候,对于中介者来说,它就会越来越庞大,越来越复杂。

使用场景

多个类之间紧密耦合的情况:类途中出现了蜘蛛网状结构,使用中介者模式,有利于把网状结构梳理为星型结构。

中介者和同事角色需要抽象出接口吗

先说中介者,中介者用于处理类之间的交互,通常,一个中介者就够了,把它抽象出一个抽象类,感觉没有必要;对于同事角色,它们各有各的“个性”,在中介者注入的时候也不会使用抽象类注入(中介者保存的同事角色字段使具体的类型),所以,中介者也可以不抽象。抽象出来可能更多的是为了符合这个模式的定义,实际在使用的时候,并不会用到抽象类。

个人的理解:终结模式使用了代理模式

其实和代理模式还是有一点区别,代理模式种,代理对象和被代理的对象实现了同样的接口。

代理模式,是一种结构型模式,它为对象提供了代理,用来控制这个对象的访问。

代理模式的一个优点就是保证具体的主题角色(这里就是具体的同事角色)职责的清晰,通过代理对象(中介者)来处理被代理对象之间的交互。同事角色A与其他同事角色交互时,其他同事角色被代理,同事角色只需要调用中介者(代理对象)的方法。

每个同事角色与其他角色交互时,并不是直接的访问,而是通过代理对象访问。

发布了213 篇原创文章 · 获赞 116 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq2071114140/article/details/103673054