从中国加入WTO来看Java设计模式:中介者模式
应用场景
- 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
中介者模式
定义
包装了一系列对象相互作用的方式,使得这些对象不必互相明显引用,从而使得他们比较松散的耦合
设计原则:迪米特法则
意图
使用一个中介对象来封装一系列的对象交互,中介者使得这些对象不必互相明显引用,从而使得他们比较松散的耦合,而且可以独立的改变他们之间的交互
主要解决问题
系统的对象与对象之间存在大量的关联,这样就会导致系统的结构变的复杂,如果一个对象发生了改变,就需要跟踪与其关联的对象
何时使用
多个类相互耦合,形成了网状结构,要把网状结构变成星状结构
网状结构:
这些对象即会影响别的对象,又会被别的对象影响,因此常常叫做同事对象,从图中可以看出,几乎每一个对象都和其他对象发生相互作用,这是一个过度耦合的系统
星状结构:
通过引入中介者对象,可以把系统的网状结构变成星状结构,可以看出,同事对象之间不再通过直接的联系与其他对象发生关系,中介者对象的存在保证了对象结构上的稳定,也就是说,系统不会因为新对象的引入而造成大量的修改工作
优缺点
优点:
- 降低了类的复杂度,将一对多转化成了一对一
- 各个类之间解耦了
- 符合设计原则:迪米特法则
缺点:
- 增加了中介者类的复杂度
结构图:
涉及的角色:
- 抽象中介者(Mediator)角色:定义出同事对象到中介者对象的接口,其中主要的方法是一个或者多个事件方法,这个角色一般是有一个Java抽象类或者Java对象实现
- 具体中介者(ConcreteMediator)角色:实现了抽象中介者角色所声明的事件方法,具体中介者角色知晓所有的具体同事类,它从具体同事类接收消息、向具体同事对象发出命令,一般是由一个具体Java类实现
- 抽象同事类(Colleague)角色:定义出中介者到同事对象的接口,同事对象只知道中介者而不知道其他的同事对象
- 具体同事类(ConcreteColleague)角色:每一个具体同事类都知道它自己在小范围的行为,而不知道它在大范围的目的
对应源码如下:
public abstract class Mediator {
/** 事件方法,由子类实现 */
public abstract void colleagueChanged(Colleague colleague);
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
mediator.create();
Colleague colleague1 = new Colleague1(mediator);
Colleague colleague2 = new Colleague2(mediator);
mediator.colleagueChanged(colleague1);
}
}
public class ConcreteMediator extends Mediator {
private Colleague1 colleague1;
private Colleague2 colleague2;
@Override
public void colleagueChanged(Colleague colleague) {
colleague1.action();
colleague2.action();
}
/** 创建同事对象 */
public void create() {
colleague1 = new Colleague1(this);
colleague2 = new Colleague2(this);
}
/** 提供同事对象 */
public Colleague1 getColleague1() {
return colleague1;
}
/** 提供同事对象 */
public Colleague2 getColleague2() {
return colleague2;
}
}
public abstract class Colleague {
private Mediator mediator;
/** 参量:中介者对象 */
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
/** 取值方法 */
public Mediator getMediator() {
return mediator;
}
/** 行动方法,由子类实现 */
public abstract void action();
/** 可以改变对象的内部状态 */
public void change() {
mediator.colleagueChanged(this);
}
}
public class ConcreteColleague extends Colleague {
/**
* 参量:中介者对象
*
* @param mediator
*/
public ConcreteColleague(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
System.out.println("实现了行动方法");
}
}
世界贸易组织WTO
世界贸易组织(英语:World Trade Organization),简称世贸组织(WTO),是一个独立于联合国的永久性国际组织。世界贸易组织的职能是调解纷争加入WTO不算签订一种多边贸易协议。它是贸易体制的组织基础和法律基础,还是众多贸易协定的管理者、各成员贸易立法的监督者、以及为贸易提供解决争端和进行谈判的场所
比如在没有WTO的时候,各个国家之间的贸易往来是这样的:
有了WTO之后,贸易往来变成了下图所示:
小场景:
中国、法国、韩国三个国家需要通过WTO进行贸易往来,中国的茶叶需要出口到法国和韩国,法国的鹅肝需要出口到中国和韩国,而韩国的泡菜也需要出口到中国和法国
WTO组织,即抽象中介者:
定义了两个接口,加入WTO和贸易往来:
public interface WTOMediator {
/** 加入WTO */
void addWTO(Countries countries);
/** 贸易往来 */
void trade(Countries countries);
}
具体中介者,实现了上面的接口,定义了如何加入WTO和如何进行贸易往来:
public class ConcreteWTOMediator implements WTOMediator {
private List<Countries> countriesList = new ArrayList<>();
@Override
public void addWTO(Countries countries) {
if (!countriesList.contains(countries)) {
countries.setWtoMediator(this);
this.countriesList.add(countries);
}
}
@Override
public void trade(Countries countries) {
countriesList.forEach(v -> {
if(!v.equals(countries)) {
v.receive();
}
});
}
}
抽象同事类,知道WTO的存在,但是不知道其他国家的存在:
public abstract class Countries {
public WTOMediator wtoMediator;
/** 贸易进口 */
public abstract void receive();
/** 贸易出口 */
public abstract void send();
public void setWtoMediator(WTOMediator wtoMediator) {
this.wtoMediator = wtoMediator;
}
}
中国、法国、韩国各个国家需要实现上面的接口:
public class China extends Countries {
@Override
public void receive() {
System.out.println("贸易出口到中国");
}
@Override
public void send() {
System.out.println("中国茶叶出口了!");
this.wtoMediator.trade(this);
}
}
public class French extends Countries {
@Override
public void receive() {
System.out.println("贸易出口到法国");
}
@Override
public void send() {
System.out.println("法国鹅肝出口了!");
this.wtoMediator.trade(this);
}
}
public class Korea extends Countries {
@Override
public void receive() {
System.out.println("贸易出口到韩国");
}
@Override
public void send() {
System.out.println("韩国泡菜出口了!");
this.wtoMediator.trade(this);
}
}
下面是测试类,即开始进行贸易往来了:
public class Test {
public static void main(String[] args) {
//构建WTO中介者
WTOMediator mediator = new ConcreteWTOMediator();
//构建具体的同事类,即各个国家
Countries china = new China();
Countries french = new French();
Countries korea = new Korea();
//加入WTO
mediator.addWTO(china);
mediator.addWTO(french);
mediator.addWTO(korea);
china.send();
System.out.println();
french.send();
System.out.println();
korea.send();
}
}
类图:
注意事项:
- 不应当在职责划分混乱的时候使用中介者模式
- 不应当对数据类和方法类使用
- 需要正确的理解封装
与中介者模式有关的设计模式:
- 外观模式
- 观察者模式
- 适配器模式
请看完上面四个模式后思考,它们的异同在哪里