中介者模式

  • 定义:定义一个封装一组如何交互的对象,通过使对象明确的相互引用来促进松散耦合,并允许独立地改变它们的交互
  • 类型:行为型
  • 适用场景:
    • 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
    • 交互的公共行为,如果需要改变行为则可以增加新的中介者类
  • 优点:
    • 将一对多转化为一对一、降低程序复杂度
    • 类之间解耦
  • 缺点:
    • 中介者过多,导致系统复杂
  • 相关设计模式:
    • 中介者模式和观察者模式:有时候会结合使用,用观察者模式来实现中介者模式角色间的通讯

coding

抽象同事类

/**
 * <p>
 *     抽象的同事类,也叫抽象组件,以前互相依赖的各个对象或组件,互
 *     相之间以“同事” 称呼。主要定义一些各个具体同事类之间共有的方法。
 * </p>
 *
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public abstract class Colleague {
    /**聚合(弱关联)中介者对象*/
    private Mediator mediator;
    private String name;
    public Colleague(String name,Mediator mediator){
        this.name = name;
        this.mediator = mediator;
    }
    public void receiveMsg(String name,String message){
        String sex = this instanceof BoyColleague ? "男" : "女";
        System.out.println(String.format("%s同事%s收到来自%s的消息:%s",sex,getName(),name,message));
        doReceiveMsg(name,message);
    }
    public abstract void doReceiveMsg(String name,String message);
}

 

具体同事类

/**
 * <p>
 *     具体的同事类,Colleague 的具体实现类。
 *     当一个同事类想要调用另一个同事的方法的时候,它必须调用中介者的方法,
 *     中介者中的方法再去调用其他同事的方法。
 *     男同事
 * </p>
 *
 */
public class BoyColleague extends Colleague {

    public BoyColleague(String name){
        this.setName(name);
    }

    public BoyColleague(String name,Mediator mediator){
        super(name,mediator);
        /**把自己的信息登记到hr那*/
        getMediator().register(this);
    }
    /**发出约会信息*/
    public void engagement (String content) {
        getMediator().contact(new BoyColleague(getName()),content);
    }

    @Override
    public void doReceiveMsg(String name ,String message) {
        /**do nothing*/
    }
}
/**
 * <p>
 *     具体的同事类,Colleague 的具体实现类。
 *     当一个同事类想要调用另一个同事的方法的时候,它必须调用中介者的方法,
 *     中介者中的方法再去调用其他同事的方法。
 *     女同事
 * </p>
 *
 */
public class GirlColleague extends Colleague {

    public GirlColleague(String name,Mediator mediator){
        super(name,mediator);
        /**把自己的信息登记到hr那*/
        getMediator().register(this);
    }

    public void agree(String name) {
        getMediator().contact(this,String.format(
                "%s,你好,我是%s,你就是我好找的人,我们去约会吧!",name,getName()
        ));
    }

    public void degree(String name){
        getMediator().contact(this,String.format(
                "%s,你好,我是%s,我们俩不合适,抱歉!",name,getName()
        ));
    }

    @Override
    public void doReceiveMsg(String name , String message) {
        if (message.contains("高") || message.contains("富") || message.contains("帅")){
            agree(name);
        }else{
            degree(name);
        }
        System.out.println("===========================");
    }
}

 

抽象中介者

/**
 * <p>抽象中介者角色,主要定义一个接口,用于各个同事之间进行互相通信。与同事类相互依赖。</p>
 *
 */
public abstract class Mediator {
    Set<Colleague> colleagues;
    public void register(Colleague colleague){
        if (colleagues == null){
            colleagues = new HashSet<>(16);
        }
        this.colleagues.add(colleague);
    }
    public Set<Colleague> getColleagues(){
        return this.colleagues;
    }
    public abstract void contact(Colleague colleague,String message);
}

 

具体中介者

/**
 * <p>人事中介者,负者联络公司男女同事之间的情愫</p>
 *
 */
public class HrMediator extends Mediator{

    @Override
    public void contact(Colleague colleague, String message) {
        this.getColleagues().forEach(col->{
            if (colleague != col){
                if (colleague instanceof BoyColleague && col instanceof GirlColleague){
                    /** 男同事发给女同事 */
                    col.receiveMsg(colleague.getName(),message);
                }
                if (colleague instanceof GirlColleague && col instanceof BoyColleague){
                    if (message.contains(col.getName())){
                        /** 女同事匹配男同事 */
                        col.receiveMsg(colleague.getName(),message);
                    }
                }
            }
        });
    }
}

 

UML

 

测试

/**
 * <p>中介者测试</p>
 *
 */
public class MediatorTest {

    public static void main(String[] args) {
        HrMediator mediator = new HrMediator();
        BoyColleague boy1 = new BoyColleague("张富贵",mediator);
        BoyColleague boy2 = new BoyColleague("李奋斗",mediator);
        BoyColleague boy3 = new BoyColleague("刘无能",mediator);
        GirlColleague girl = new GirlColleague("韩美丽",mediator);
        boy1.engagement("我就是高富帅,希望结交一位温柔贤惠的女士作为另一半!");
        boy2.engagement("我很上进,工作很认真,我希望在这里找到我爱的人!");
        boy3.engagement("话不多说,我喜欢女的,活的!");
    }

    /**
     * 中介者模式很简单,就不多说了,也不在多举例子了,
     * 像服务注册与发现中心、现实中的房屋中介、婚介所等都是应用场景。
     */
}
===========输出===========
女同事韩美丽收到来自张富贵的消息:我就是高富帅,希望结交一位温柔贤惠的女士作为另一半!
男同事张富贵收到来自韩美丽的消息:张富贵,你好,我是韩美丽,你就是我好找的人,我们去约会吧!
===========================
女同事韩美丽收到来自李奋斗的消息:我很上进,工作很认真,我希望在这里找到我爱的人!
男同事李奋斗收到来自韩美丽的消息:李奋斗,你好,我是韩美丽,我们俩不合适,抱歉!
===========================
女同事韩美丽收到来自刘无能的消息:话不多说,我喜欢女的,活的!
男同事刘无能收到来自韩美丽的消息:刘无能,你好,我是韩美丽,我们俩不合适,抱歉!
===========================

 

源码中的应用

  • java.util.Timer:会发现很多方法最后调用的都是sched()方法,可以看到sched()方法,Timer就相当于是个中介者,它去协调具体的TimerTask任务类,所有的任务都会到sched()方法,进行整体的协调
public class Timer {
    ...
    public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
    }
    public void schedule(TimerTask task, Date firstTime, long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), -period);
    }
    private void sched(TimerTask task, long time, long period) {
        ...
    }
    ...
}

 

posted @ 2024-01-29 10:32  wangzhilei  阅读(3)  评论(0编辑  收藏  举报