Java Code DesignPartten

设计模式-中介者模式

Posted on 2020-09-14,5 min read

定义

  • Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and iit lets you vary their interaction independently.(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变他们之间的交互)
  • 组成
    • Mediator抽象中介者:抽象中介者定义统一的接口,用于各同事角色之间的通行
    • Concrete Mediator具体中介者角色:具体中介者角色通过协调各同时角色实现协作行为,必须依赖于各个同事角色
    • Colleague同事角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。同事类行为分为两种:
      • 同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖。
      • 依赖方法,必须依赖中介者才能完成的行为。

优点

  • 减少了类间依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖也降低了耦合

缺点

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

使用场景

中介者模式虽然简单,但是会被误用。类间的依赖是必然的,如果只是简单的几个对象的依赖关系,为了使用设计模式而加入了中介者模式,会导致中介者的逻辑复杂化。

  • 场景:
    • 类图中出现了蜘蛛网结构,使用中介者模式将其转换为星型结构
    • N个对象之间产生了相互依赖关系(N>2)
    • 多个对象有依赖关系,但是依赖的行为不确定,或有改变的可能
    • 产品开发(如MVC框架),非项目开发

代码

通用类图

中介者模式通用类图

中介者模式

类图

中介者模式类图

代码

抽象中介者(抽象类

package com.pattern.mediator;

public abstract class Mediator {
    protected Colleague1 colleague1;
    protected Colleague2 colleague2;

    // 使用getter/setter注入,因为同事类必须有中介者,而中介者却可以只有部分同事类
    public Colleague1 getColleague1() {
        return colleague1;
    }

    public Colleague2 getColleague2() {
        return colleague2;
    }

    public void setColleague1(Colleague1 colleague1) {
        this.colleague1 = colleague1;
    }

    public void setColleague2(Colleague2 colleague2) {
        this.colleague2 = colleague2;
    }
    public abstract void doSometing1();
    public abstract void doSomething2();
}

具体中介者(继承自抽象类

package com.pattern.mediator;

public class ConcreteMediator extends Mediator {
    @Override
    public void doSometing1() {
        super.colleague1.selfMethod1();
        super.colleague2.selfMethod2();
    }

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

同事类抽象(抽象类)「需要产生依赖的类」

package com.pattern.mediator;

public abstract class Colleague {
    // 定义中介者
    protected Mediator mediator;
    public Colleague(Mediator mediator){
        this.mediator = mediator;
    }
}

具体同事类1(继承自抽象类

package com.pattern.mediator;

public class Colleague1 extends Colleague {
    public Colleague1(Mediator mediator) {
        super(mediator);
    }
    public void selfMethod1(){
        System.out.println("同事1自己的自有业务逻辑");
    }
    // 依赖方法,单独同事不能完成需要依靠中介者协调才能完成的业务(即需要调用其他同事类才能完成的任务)
    public void depMethod1(){
        System.out.println("同事1通过中介者调用的业务逻辑");
        super.mediator.doSometing1();
    }
}

具体同事类2(继承自抽象类

package com.pattern.mediator;

public class Colleague2 extends Colleague {
    public Colleague2(Mediator mediator) {
        super(mediator);
    }
    public void selfMethod2(){
        System.out.println("同事2自己的自有业务逻辑");
    }
    // 依赖方法,单独同事不能完成需要依靠中介者协调才能完成的业务(即需要调用其他同事类才能完成的任务)
    public void depMethod2(){
        System.out.println("同事2通过中介者调用的业务逻辑");
    }
}

测试代码

package com.pattern;

import com.pattern.mediator.*;
import org.junit.Test;

public class MediatorTest {
    @Test
    public void Test(){
        System.out.println("--------创建一个中介者--------");
        Mediator mediator = new ConcreteMediator();
        System.out.println("--------创建一个同事类--------");
        Colleague1 colleague1 = new Colleague1(mediator);
        Colleague2 colleague2 = new Colleague2(mediator);
        mediator.setColleague1(colleague1);
        mediator.setColleague2(colleague2);
        System.out.println("--------同事类调用自己的方法--------");
        colleague1.selfMethod1();
        System.out.println("--------同事类调用依赖的方法(通过中介者与其他类产生依赖的方法)--------");
        colleague1.depMethod1();

    }
}

结果

中介者模式运行结果

注意

  • 在中介者模式(中介者中)中很少用到接口或抽象类,因为这些类是协作关系,完成不同的任务,处理不同的业务。
  • 中介者中的方法,复杂业务的实现是依赖同事类来完成的
  • 同事类最好使用构造函数注入中介者,中介者使用getter/setter注入同事类;因为同事类必须有中介者,而中介者可以只有部分同事类
  • 不要刻意追求使用中介者模式

下一篇: 设计模式-原型模式→

loading...