1.应用场景

世界上存在着各种各样的数据库,不同数据库有各自的应用场景,对于同一份数据,最开始可能使用关系型数据库(如MySQL)进行存储查询,使用Redis作为缓存数据库,当数据量较大时使用MySQL进行查询可能较慢,所以需要将数据同步到Elasticsearch或者列式数据库如Hbase中进行大数据查询。如何设计数据同步方案是一个重要的问题。数据源众多,目标端也众多,设计得不好可能 “牵一发而动全身”。

如果我们这样设计:每个数据源直接同步数据到目标端数据库的,如果数据库有 N 个,那么最多可能的同步作业将达到 N * N 个,当修改了其中一个数据库的某些配置,可能需要修改另外的 N - 1 个数据库的同步作业。

现在介绍另一种方案,DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS 等各种异构数据源之间高效的数据同步功能。

DataX 其实相当于一个中介,从数据源读取数据,写入到目标端,数据源不再需要维护到目标端的同步作业,只需要与 DataX 通信即可。DataX 体现了中介者模式的思想。

2. 概念

中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。

3. Class Diagram

  • Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
  • ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
  • Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
  • ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。

4. Implementation

Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构:

使用中介者模式可以将复杂的依赖结构变成星形结构:

public abstract class Colleague {public abstract void onEvent(Mediator mediator);
}
public class Alarm extends Colleague {@Overridepublic void onEvent(Mediator mediator) {mediator.doEvent("alarm");}public void doAlarm() {System.out.println("doAlarm()");}
}
public class CoffeePot extends Colleague {@Overridepublic void onEvent(Mediator mediator) {mediator.doEvent("coffeePot");}public void doCoffeePot() {System.out.println("doCoffeePot()");}
}
public class Calender extends Colleague {@Overridepublic void onEvent(Mediator mediator) {mediator.doEvent("calender");}public void doCalender() {System.out.println("doCalender()");}
}
public class Sprinkler extends Colleague {@Overridepublic void onEvent(Mediator mediator) {mediator.doEvent("sprinkler");}public void doSprinkler() {System.out.println("doSprinkler()");}
}
public abstract class Mediator {public abstract void doEvent(String eventType);
}
public class ConcreteMediator extends Mediator {private Alarm alarm;private CoffeePot coffeePot;private Calender calender;private Sprinkler sprinkler;public ConcreteMediator(Alarm alarm, CoffeePot coffeePot, Calender calender, Sprinkler sprinkler) {this.alarm = alarm;this.coffeePot = coffeePot;this.calender = calender;this.sprinkler = sprinkler;}@Overridepublic void doEvent(String eventType) {switch (eventType) {case "alarm":doAlarmEvent();break;case "coffeePot":doCoffeePotEvent();break;case "calender":doCalenderEvent();break;default:doSprinklerEvent();}}public void doAlarmEvent() {alarm.doAlarm();coffeePot.doCoffeePot();calender.doCalender();sprinkler.doSprinkler();}public void doCoffeePotEvent() {// ...}public void doCalenderEvent() {// ...}public void doSprinklerEvent() {// ...}
}
public class Client {public static void main(String[] args) {Alarm alarm = new Alarm();CoffeePot coffeePot = new CoffeePot();Calender calender = new Calender();Sprinkler sprinkler = new Sprinkler();Mediator mediator = new ConcreteMediator(alarm, coffeePot, calender, sprinkler);// 闹钟事件到达,调用中介者就可以操作相关对象alarm.onEvent(mediator);}
}运行结果:
doAlarm()
doCoffeePot()
doCalender()
doSprinkler()

5. 优点和缺点

5.1 优点

  • 通过将对象彼此解耦,可以增加对象的复用性。
  • 通过将控制逻辑集中,可以简化系统维护。
  • 可以让对象之间所传递的消息便得简单而且大幅减少。

5.2 用途和缺点

  • 中介者常常用来协调相关GUI组件
  • 中介者模式的缺点时,如果设计不当,中介者模式会变得过于复杂。

6. JDK

  • All scheduleXXX() methods of java.util.Timer
  • java.util.concurrent.Executor#execute()
  • submit() and invokeXXX() methods of java.util.concurrent.ExecutorService
  • scheduleXXX() methods of java.util.concurrent.ScheduledExecutorService
  • java.lang.reflect.Method#invoke()

Java设计模式(二十):中介者设计模式相关推荐

  1. 【白话设计模式二十二】解释器模式(Interpreter)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  2. 从零开始学java(二十六)--多维数组,多维数组存储表格数据

    从零开始学java(二十六)--多维数组 多维数组 多维数组存储表格数据 多维数组 多维数组可以看成以数组为元素的数组.可以有二维.三维.甚至更多维数组,但是实际开发中用的非常少.最多到二维数组(学习 ...

  3. 关于Java的二十篇技术热文

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 到周末了,小编给大家整理了二十篇评价不错的Java技术文章,方便学习回顾,值得收藏. 题外 ...

  4. Java笔记二十二——设计模式

    使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性,降低代码的耦合度. 设计模式基于以下几个原则: 里氏替换原则 --如果调用一个父类的方法可以成功,那么替换成子类调用也应该完全可以运行 ...

  5. Java设计模式(二十二):原型设计模式

    1. 应用场景 如果一个对象的创建总是由几种固定组件不同方式组合而成; 如果对象之间仅仅实例属性不同.将不同情况的对象缓存起来,直接克隆使用.也许这比采用传递参数重新 new 一个对象要来的快一些与工 ...

  6. 二十五:设计模式的总结

    创建型:  单例模式   简单工厂模式   工厂方法模式   抽象工厂模式  建造者模式  原型模式 结构型:  代理模式   适配器模式   装饰器模式   桥接模式   组合模式   享元模式  ...

  7. 二十四种设计模式之策略模式

    一.什么是策略模式? 简单来说,策略模式是将每一个算法封装到拥有共同接口的不同类中,使得算法可以在不影响客户端的情况下发生变化.(也可以理解为可供程序运行时选择的(不同的类==不同的解决方案)). 策 ...

  8. 二十四种设计模式之代理模式

    一.什么是代理模式? 简单来说,代理模式就相当于我们生活中的中介,比如我们租房子通过房产中介或者是租房的app,买电影票通过app,就是我们实现事情的一个媒介. 二.代理模式实例 1.就比如说,程序员 ...

  9. Java设计模式(二十一):备忘录设计模式

    1. 应用场景 备忘录模式经常可以遇到,譬如下面这些场景: 浏览器回退:浏览器一般有浏览记录,当我们在一个网页上点击几次链接之后,可在左上角点击左箭头回退到上一次的页面,然后也可以点击右箭头重新回到当 ...

最新文章

  1. 【MAC】记mac中django-admin.py 调用失败的解决方案
  2. sdio接口_多种接口的谷歌Coral模块,总有一款适合您~
  3. 北京赛区总结,以及。。。
  4. 【Java 网络编程】TCP 传输机制 ( 数据拆分 | 排序 | 顺序发送 | 顺序组装 | 超时重发 )
  5. 【poi xlsx报错】使用POI创建xlsx无法打开
  6. python tkinter button颜色变不了_tkinter多按钮颜色变化
  7. 除了 Tensorflow、PyTorch ,还有哪些深度学习框架值得期待?
  8. mermaid流程图工具_Markdown高级使用之流程图
  9. 编码技术新突破:字节跳动AVG让视频缩小13%
  10. web网站服务(二)-1
  11. linux 6.4 nfs配置,RHEL6.4 NFS文件共享服务器搭建
  12. JavaScript数组属性与方法
  13. word转PDF图片很糊or word自带公式编辑器公式自动编号转PDF括号没了
  14. 计算机博弈 六子棋 人机/人人对弈系统开发
  15. 求最大值 最小值 下标 及格率 c语言,输入某班的C语言成绩,计算输出其及格率...
  16. 视觉目标跟踪漫谈:从原理到应用
  17. 深圳六月有哪些公园能赏花 赏花打卡点推荐
  18. Java实验01 Java编程基础(猜数字游戏、随机点名器)
  19. 【葡萄城报表案例分享】项目施工进度报告 – 树形报表
  20. 南卡蓝牙耳机和JBL蓝牙耳机哪个更值得买?音质最好的蓝牙耳机测评

热门文章

  1. MongoDB学习之路(三)
  2. android shortcut livefoulder
  3. Java性能优化(12):最小化类和成员可访问能力
  4. Effective C++ 读书笔记之Part2.Constructors, Destructors, and Assignment Operators
  5. 2013ACM多校联合(2)
  6. 如何在XSLT里调用C#的代码
  7. MSP430程序库五SPI同步串行通信
  8. 63.死锁和死锁的原因
  9. 为什么Python是数据科学领域最受欢迎的语言
  10. 马斯克的“大脑改造计划”,还需要点亮哪些技能树?