中介者设计模式

中介者设计模式


1. 简单介绍

中介者设计模式(Mediator)是一种行为型设计模式。该模式引入中介对象来封装一系列的对象交互,并使这一系列的对象之间原本需要相互调用的依赖关系,全部转成对中介对象的单独依赖,即将多个对象的依赖关系由网状模型的转变成星状模型,从而使多个对象之间松耦合。

2. 使用场景
  • 系统中对象之间存在比较复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象,可以引入中介这模式,将多个逻辑关联的对象之间进行解耦
3. 场景举例

DataX是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括MySQLOracleSqlServerPostgreHDFSHiveADSHBaseTableStore(OTS)MaxCompute(ODPS)DRDS等各种异构数据源之间高效的数据同步功能。DataX其实相当于一个中介,从数据源读取数据,写入到目标端,数据源不再需要维护到目标端的同步作业,只需要与DataX通信即可。DataX体现了中介者模式的思想。

4. UML类图

中介者模式UML类图

5. 具体实现

描述

  • 背景:买房者、卖房子通过告知房屋中介,各自的房屋买卖预期心里价位,由中介来判断是否进行交易。如果买卖双方心里预期价位一直,则交易成功,否则交易失败
  • Colleague:抽象同事类
  • BuyerColleague:卖家,对应设计模式中的具体同事角色
  • SellerColleague:卖家,对应设计模式中的具体同事角色
  • Mediator:抽象中介者类,对应中介者模式中的Mediator角色
  • HousingAgent:房屋中介者,对应中介者模式中的具体中介者

代码实现

Mediator.java

/**
 * 抽象中介者类,对应中介者模式中的Mediator角色
 */
public abstract class Mediator {

    /**
     * 具体同事类注册到中介者
     * @param colleague 具体同事
     */
    public abstract void register(Colleague colleague);

    /**
     * 供同事类调用
     * 买家(或卖家)注册到中介者中之后,通过调用该方法买告诉中介公司自己的买房要求(卖方要求)
     */
    public abstract void agent();
}

HousingAgent.java

/**
 * 房屋中介者,对应中介者模式中的具体中介者
 */
public class HousingAgent extends Mediator {

    private Map<String, Colleague> colleagueMap = new HashMap<>();

    @Override
    public void register(Colleague colleague) {
        colleagueMap.put(colleague.getName(), colleague);
    }

    @Override
    public void agent() {
        Colleague seller = colleagueMap.get("seller");
        Colleague buyer = colleagueMap.get("buyer");
        if (seller != null && buyer != null) {
            int sellerExpectedHousePrices = seller.getExpectedHousePrices();
            int buyerExpectedHousePrices = buyer.getExpectedHousePrices();
            if (buyerExpectedHousePrices >= sellerExpectedHousePrices) {
                System.out.println("买卖双方房屋期望价格一直,完成交易");
            } else {
                System.out.println("卖家出售房屋价格高于买家预期,停止交易");
            }
        } else if (seller != null) {
            System.out.println("等待买家出价");
        } else {
            System.out.println("等待卖家出价");
        }
    }
}

Colleague.java

/**
 * 抽象同事类,对应中介者模式中的Colleague角色
 */  
public abstract class Colleague {

    private Mediator mediator;

    /**
     * 买家、卖家心中预期房子售价价位
     */
    private int expectedHousePrices;

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

    /**
     * 标识具体同事类的名称
     */
    public abstract String getName();

    public void sendAppeal() {
        mediator.agent();
    }

    public int getExpectedHousePrices() {
        return expectedHousePrices;
    }

    public void setExpectedHousePrices(int expectedHousePrices) {
        this.expectedHousePrices = expectedHousePrices;
    }
}

BuyerColleague.java

/**
 * 买家,对应设计模式中的具体同事角色
 */
public class BuyerColleague extends Colleague {

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

    @Override
    public String getName() {
        return "buyer";
    }
}

SellerColleague.java

/**
 *  卖家,对应设计模式中的具体同事角色
 */
public class SellerColleague extends Colleague {

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

    @Override
    public String getName() {
        return "seller";
    }
}
7. 源码展示

JDK中的Timer类在任务调度设计中采用了中介者设计模式的思想。待处理的任务(TimeTask)通过添加(注册)到Timer类中,何时调用由Timer进行管理。其中TimerTask对应中介者模式中的Colleague角色,Timer对应中介者模式中的ConcreteMediator角色。主要核心代码如下:

Timer.java

/**
 * 对应中介者模式中的ConcreteMideator角色
 */
public class Timer {
    /**
     * 存放任务的(具体同事对象)队列
     */
    private final TaskQueue queue = new TaskQueue(); 

    /**
     * 任务交给Timer进行管理
     */
    public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }
   
   /**
    * 控制着任务的入队,任务之间入队执行存在的线程安全问题全部交由中介者Timer处理
    */
   private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    } 

    /**
     * 任务的具体执行
     */
    public void run() {
        try {
            // 控制者任务的具体执行过程
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }
}

TimeTask.java

public abstract class TimerTask implements Runnable {
    
    protected TimerTask() {
    }

    /**
     * 子类重写该方法完成具体的任务逻辑
     * 任务交由Timer类进行管理、调用
     */
     public void abstract run();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值