欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java设计模式(22)之中介者模式

程序员文章站 2024-03-23 08:31:34
...

中介者模式

用一个中介者对象来封装一系列对象的交互,中介者使各对象不需要显示的相互应用,从而使其耦合松散,而且可以独立的改变他们之间的交互。使用中介者模式集中管理多个对象之间复杂的沟通方式。

类型:

行为型模式(通过中间类的行为型模式)

中介者模式中的几个角色:

  • 抽象的中介者角色(Mediator):定义Colleague之间的交互方式的接口,如果具体中介者对象有多个,可以抽象出来,否则可以合并两者。
  • 具体的中介者角色(ConcreteMediator):具体的中介者对象中,必须知道所有的ConcreteColleague对象,并且实现他们之间的交互方式。
  • 抽象的同事类对象(Colleague):定义具体同事类的接口。
  • 具体的同事类对象(ConcreteColleague):每个具体的ConcreteColleague对象只知道自身的行为,而不知道其他的同事类对象的情况,但是都知道中介者对象。

中介者模式关系图:

Java设计模式(22)之中介者模式

帮助理解的图:

Java设计模式(22)之中介者模式

中介者模式示例:

抽象的中介者角色(Mediator):

/**
 * Create by zhaihongwei on 2018/4/4
 * 抽象的中介者对象
 */
public interface Mediator {

    /**
     * 给具体Colleague发送消息
     * @param message
     * @param colleague
     */
    void sendMessage(String message,Colleague colleague);
}

具体的中介者角色(ConcreteMediator):

/**
 * Create by zhaihongwei on 2018/4/4
 * 具体中介者对象
 */
public class ConcreteMediator implements Mediator {

    /**
     * 中介者对象需要知道所有的Colleague对象
     */
    public ColleagueA colleagueA;
    public ColleagueB colleagueB;

    public void setColleagueA(ColleagueA colleagueA) {
        this.colleagueA = colleagueA;
    }
    public void setColleagueB(ColleagueB colleagueB) {
        this.colleagueB = colleagueB;
    }

    /**
     * 一个Colleague的改变,影响其他的Colleague
     * @param message
     * @param colleague
     */
    @Override
    public void sendMessage(String message, Colleague colleague) {

        if (colleague == colleagueA) {
            colleagueB.getMessage(message);
        } else if (colleague == colleagueB) {
            colleagueA.getMessage(message);
        }
    }
}

抽象的同事类对象(Colleague):

/**
 * Create by zhaihongwei on 2018/4/4
 * 抽象同事类
 */
public abstract class Colleague {

    public Mediator mediator;

    /**
     * 通过构造方法接收中介者对象
     * @param mediator
     */
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    /**
     * 接受其他Colleague对象发送的消息
     * @param message
     */
    public abstract void getMessage(String message);

    /**
     * 发送消息,给其他的Colleague对象
     * @param message
     */
    public abstract  void sendMessage(String message);
}

具体的同事类对象(ConcreteColleague):

/**
 * Create by zhaihongwei on 2018/4/4
 */
public class ColleagueA extends Colleague {

    /**
     * 通过构造方法接收中介者对象
     * @param mediator
     */
    public ColleagueA(Mediator mediator) {
        super(mediator);
    }

    @Override
    /**
     * 具体的Colleague对象给具体的Colleague对象发送消息通过中介者对象来完成
     */
    public void getMessage(String message) {
        System.out.println("ColleagueA获得消息:" + message);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage("ColleagueA发送的消息--->>>" + message,this);
    }
}
/**
 * Create by zhaihongwei on 2018/4/4
 */
public class ColleagueB extends Colleague {

    /**
     * 通过构造方法接收中介者对象
     * @param mediator
     */
    public ColleagueB(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void getMessage(String message) {
        System.out.println("ColleagueB获得消息:" + message);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage("ColleagueB发送的消息--->>>"+ message,this);
    }
}

测试类:

/**
 * Create by zhaihongwei on 2018/4/4
 */
public class MediatorTest {

    public static void main(String[] args) {
        // 创建具体中介者对象
        ConcreteMediator mediator = new ConcreteMediator();

        // 创建ColleagueA和ColleagueB对象
        ColleagueA colleagueA = new ColleagueA(mediator);
        ColleagueB colleagueB = new ColleagueB(mediator);

        mediator.setColleagueA(colleagueA);
        mediator.setColleagueB(colleagueB);

        String messageA = "中介者模式就是这样的么?";
        colleagueA.sendMessage(messageA);
        String messageB = "中介者模式就是这样的";
        colleagueB.sendMessage(messageB);
    }
}

测试结果:

ColleagueB获得消息:ColleagueA发送的消息--->>>中介者模式就是这样的么?
ColleagueA获得消息:ColleagueB发送的消息--->>>中介者模式就是这样的

如果每一个ConcreteColleague对象的改变都会影响到其他所有的ConcreteColleague对象,可以将中介者对象进行如下改进:

/**
 * Create by zhaihongwei on 2018/4/4
 * 具体中介者对象
 */
public class ConcreteMediator implements Mediator {

    public Set<Colleague> colleagues = new HashSet<>();

    /**
     * 添加具体的ConcreteColleague对象
     * @param colleague
     */
    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }

    /**
     * 删除指定的ConcreteColleague对象
     * @param colleague
     */
    public void removeColleague(Colleague colleague) {
        colleagues.remove(colleague);
    }

    /**
     * 一个Colleague的改变,影响其他的Colleague
     * @param message
     * @param colleague
     */
    @Override
    public void sendMessage(String message, Colleague colleague) {
        if(colleagues.contains(colleague)) {
            colleagues.remove(colleague);
            // 改变其他的所有Colleague对象
            for (Colleague coll : colleagues) {
                coll.getMessage(message);
            }
            colleagues.add(colleague);
        }
    }
}

总结:

通过上面的例子可以看到,一个具体的Colleague对象的行为会影响到其他的Colleague对象,所以通过中介者的方式,避免了具体的Colleague对象之间的交互。虽然这样可以减少ConcreteColleague之间的耦合,但是会使得ConcreteMediator的责任变得过于庞大。

中介者模式的优缺点:

优点:

  • 减少了ConcreteColleague对象之间的耦合。增加了抽象Mediator和Colleague对象的复用性。
  • 将ConcreteColleague交互逻辑集中管理,简化维护。
  • 减少了ConcreteColleague对象间的直接交互,减少各个对象之间的交互代码的编写。

缺点:

  • 如果设计不当,中介对象本身会变得特别复杂。
相关标签: 中介者模式