设计模式(10)——中介者模式

本文介绍中介者模式的概念和应用。

基本思想和原则

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

动机

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
public class AutoDealer {
private AutoManufacturer autoManufacturer;
private InsuranceCompany insuranceCompany;
private Customer customer;

public void setAutoManufacturer(AutoManufacturer autoManufacturer) {
this.autoManufacturer = autoManufacturer;
}

public AutoManufacturer getAutoManufacturer() {
return autoManufacturer;
}

public void setInsuranceCompany(InsuranceCompany insuranceCompany) {
this.insuranceCompany = insuranceCompany;
}

public InsuranceCompany getInsuranceCompany() {
return insuranceCompany;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}

public Customer getCustomer() {
return customer;
}

// 签订保险协议
public void signInsuranceAgreement() {
this.insuranceCompany.draftInsuranceAgreement();
this.customer.payForInsurance();
}

// 购买汽车
public void buyCar() {
this.autoManufacturer.produceCar();
this.customer.payForCar();
}
}

public class AutoManufacturer {
private AutoDealer autoDealer;

public AutoManufacturer(AutoDealer autoDealer) {
this.autoDealer = autoDealer;
}

// 生产汽车
public void produceCar() {
System.out.println("Auto manufacturer produce car.");
}
}

public class Customer {
private AutoDealer autoDealer;

public Customer(AutoDealer autoDealer) {
this.autoDealer = autoDealer;
}

public void payForInsurance() {
System.out.println("Customer pay for insurance.");
}

public void payForCar() {
System.out.println("Customer pay for car.");
}

// 签订保险协议
public void signInsuranceAgreement() {
this.autoDealer.signInsuranceAgreement();
}

// 购买汽车
public void buyCar() {
this.autoDealer.buyCar();
}
}

public class InsuranceCompany {
private AutoDealer autoDealer;

public InsuranceCompany(AutoDealer autoDealer) {
this.autoDealer = autoDealer;
}

// 起草保险协议
public void draftInsuranceAgreement() {
System.out.println("Insurance company draft an insurance agreement.");
}
}

public class Test {
public static void main(String[] args) {
AutoDealer autoDealer = new AutoDealer();
AutoManufacturer autoManufacturer = new AutoManufacturer(autoDealer);
InsuranceCompany insuranceCompany = new InsuranceCompany(autoDealer);
Customer customer = new Customer(autoDealer);
autoDealer.setAutoManufacturer(autoManufacturer);
autoDealer.setInsuranceCompany(insuranceCompany);
autoDealer.setCustomer(customer);

customer.buyCar();
customer.signInsuranceAgreement();
}
}

输出如下:

1
2
3
4
Auto manufacturer produce car.
Customer pay for car.
Insurance company draft an insurance agreement.
Customer pay for insurance.

上面的代码模拟了一个消费者购买汽车的过程,这里面存在四个基本实体:汽车厂家、保险公司、汽车经销商和消费者。具体的交互过程主要有两个:消费者订购汽车和消费者为汽车购买保险。消费者订购汽车的过程是:厂家生产一辆汽车,消费者付款购买汽车。消费者为汽车购买保险的过程是,保险公司起草一份保险协议,消费者付款购买保险。现实中的过程要比这个复杂一些,这里为了好理解做了简化处理。

很明显这里面存在多方交互的问题,消费者——汽车经销商——汽车厂家,消费者——汽车经销商——保险公司,这里的汽车经销商其实就是一个中介者,负责协调多方实现某个过程。作为消费者,购买汽车时并不需要直接去找具体的汽车厂家,而是让汽车经销商来协调这一切,最后完成购买。买汽车保险也是类似,汽车经销商会帮你搞定一切保险事宜,消费者最后只需要签字并付款即可。

在中介者模式的实现上,要注意中介者需要在内部维护各个具体类的实例,各个具体类也需要维护一个中介者的实例,当具体类需要调用其他类的方法时(即和其他类产生了交互),应该调用中介者中某个方法,让中介者来协调这一系列的调用,中介者在这个方法中通过调用各个具体类的方法来完成整个过程。

优点

当有多个类相互之间有很多交互时,使用中介者模式可以减少类之间的耦合,原本一个具体的实现类需要依赖于多个类,现在只需要依赖中介者。

缺点

中介者模式的缺点很明显,当具体实现类增加,类之间的交互增加时,中介者会变得非常庞大和臃肿。实际编码过程中应当注意这个问题,在必要时做进一步的拆分。