一、介绍
- 中介者模式也叫调停者模式,是一种比较简单的模式
- 用一个中介对象封装一系列对象(同事)的交互,中介者使各对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变它们之间的交互。
二、原理类图
2.1 角色和职责
- 抽象中介者(Mediator)角色:该角色定义出同事对象到中介者对象的统一接口,用于各同事角色之间的通信。
- 具体中介者(Concrete Mediator)角色:该角色实现抽象中介者,它依赖于各个同事角色,并通过协调各同事角色实现协作行为。
- 抽象同事(Colleague)角色:该角色定义出中介者到同事对象的接口,同事对象只知道中介者而不知道其余的同事对象。
- 具体同事(Concrete Colleague)角色:该角色实现抽象同事类,每一个具体同事类都清楚自己在小范围内的行为,而不知道大范围内的目的。
2.2 代码分析
- 抽象中介者Mediator的代码如下所示。
【代码 6-1】 Mediator.java
//抽象中介者
public abstract class Mediator {
//中介者模式的业务逻辑方法
public abstract void colleagueChanged(Colleague c);
}
- 具体中介者ConcreteMediator的代码如下所示。
【代码 6-2】 ConcreteMediator.java
//具体中介者
public class ConcreteMediator extends Mediator {
private ConcreteColleague1 c1;
private ConcreteColleague2 c2;
//中介者模式的业务逻辑方法
public void colleagueChanged(Colleague c){
c1.action();
c2.action();
}
//工厂方法,创建同事对象
public void createConcreteMediator(){
c1=new ConcreteColleague1(this);
c2=new ConcreteColleague2(this);
}
//获取同事对象
public ConcreteColleague1 getC1() {
return c1;
}
public ConcreteColleague2 getC2() {
return c2;
}
}
- 抽象同事Colleague的代码如下所示。
【代码 6-3】 Colleague.java
//抽象同事类
public abstract class Colleague {
private Mediator mediator;
//构造函数
public Colleague(Mediator m){
this.mediator =m;
}
//getter和setter方法
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
//抽象行动方法,由子类实现
public abstract void action();
//业务方法,调用此方法改变对象的内部状态
public void change(){
this.mediator.colleagueChanged(this);
}
}
- 具体同事ConcreteColleague1和ConcreteColleague2的代码如下所示。
【代码 6-4】 ConcreteMediator1.java
//具体同事类
public class ConcreteColleague1 extends Colleague{
//构造函数
public ConcreteColleague1(Mediator m)
{
super(m);
}
//实现具体行动方法
public void action(){
System.out.println("这是同事1的行动方法!");
}
}
- 【代码 6-5】 ConcreteMediator2.java
public class ConcreteColleague2 extends Colleague{
//构造函数
public ConcreteColleague2(Mediator m)
{
super(m);
}
//实现具体行动方法
public void action(){
System.out.println("这是同事2的行动方法!");
}
}
三、优缺点
3.1 优点:
- 减少类间的依赖,将原有的一对多的依赖变成一对一的依赖,使得对象之间的关系更易维护和理解。
- 避免同事对象之间过度耦合,同事类只依赖于中介者,使同事类更易被复用,中介类和同事类可以相对独立地演化。
- 中介者模式将对象的行为和协作抽象化,将对象在小尺度的行为上与其他对象的相互作用分开处理。
3.2 缺点:
- 中介者模式降低了同事对象的复杂性,但增加了中介者类的复杂性。
- 中介者类经常充满了各个具体同事类的关系协调代码,这种代码是不能复用的。
注意事项
1. 不应在责任划分混乱时使用;
2. 不应对数据类和方法类使用
四、实例
使用中介者模式模拟婚姻中介所的工作过程。类图如下所示:
- 婚姻中介所接口MarriageAgency代码如下所示。
【描述6.D.1】 MarriageAgency.java
public interface MarriageAgency {
void pair(Person person); // 为person配对
void register(Person person); // 注册会员
}
- 人的抽象类Person的代码如下所示。
【描述6.D.1】 Person.java
public abstract class Person {
String name; // 姓名
int age; // 年龄
Sex sex; // 性别
int requestAge; // 要求对象的年龄。对对象只有这一个要求
MarriageAgency agency; // 婚姻中介
public Person(String name, int age, Sex sex, int requestAge,
MarriageAgency agency) {
this.name = name;
this.age = age;
this.sex = sex;
this.requestAge = requestAge;
this.agency = agency;
agency.register(this); // 注册会员
}
// 寻找对象
public void findPartner() {
agency.pair(this);
}
}
enum Sex {
MALE, FEMALE;
}
上述代码中除了定义Person抽象类之外,还使用枚举类型Sex对人的性别进行区分。 婚姻中介所实现类MarriageAgencyImpl实现
- MarriageAgency接口,其代码如下所示。
【描述6.D.1】 MarriageAgencyImpl.java
public class MarriageAgencyImpl implements MarriageAgency {
List<Man> men = new ArrayList<Man>(); // 男会员
List<Woman> women = new ArrayList<Woman>(); // 女会员
@Override
public void register(Person person) {
if (person.sex == Sex.MALE)
men.add((Man) person);
else if (person.sex == Sex.FEMALE)
women.add((Woman) person);
}
@Override
public void pair(Person person) {
if (person.sex == Sex.MALE) {
for (Woman w : women)
if (w.age == person.requestAge) {
System.out.println(person.name + "和" + w.name + "配对成功");
return;
}
} else if (person.sex == Sex.FEMALE) {
for (Man m : men)
if (m.age == person.requestAge) {
System.out.println(person.name + "和" + m.name + "配对成功");
return;
}
}
System.out.println("没有为" + person.name + "找到合适的对象");
}
}
上述代码中 pair()方法用于对人进行配对。当传过来的参数对象 person 的性别是男时,则在女会员列表Women 中搜索要求对象的年龄与之匹配的女性,否则就在男会员列表Men中搜索男性。
- 男人类Man和女人类Woman都是Person的子类,代码分别如下所示。
【描述6.D.1】 Man.java
public class Man extends Person {
public Man(String name, int age, int requestAge, MarriageAgency agency) {
super(name, age, Sex.MALE, requestAge, agency);
}
}
【描述6.D.1】 Woman.java
public class Woman extends Person {
public Woman(String name, int age, int requestAge, MarriageAgency agency) {
super(name, age, Sex.FEMALE, requestAge, agency);
- 【描述6.D.1】 Test.java
public class Test {
public static void main(String[] args) {
MarriageAgency agency = new MarriageAgencyImpl();
Person m1 = new Man("John", 20, 18, agency);
Person m2 = new Man("Mike", 27, 25, agency);
Person w1 = new Woman("Mary", 25, 27, agency);
Person w2 = new Woman("Jane", 20, 22, agency);
m1.findPartner();
m2.findPartner();
}
}
- 运行后结果如下。
没有为John找到合适的对象
Mike和Mary配对成功