一、中介者模式概述
定义:
中介者模式:定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显示的相互引用,从而使其耦合松散,而且用户可以独立地改变它们之间的交互。
中介者模式可以将系统的网状结构变成以中介者为中心的星行结构。
中介者模式是迪米特法则的一个典型应用。
二、中介者模式的结构和实现
2.1 中介者模式的结构
中介者模式包含一些4个角色:
- mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
- ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
- Colleague(抽象同事类):定义各个同事类公有的方法,并声明了一些抽象方法供子类实现。
- ConcreteColleague(具体同事类):它是抽象同事类的子类,每一个同事对象在需要与其他同事对象通信时先与中介者通信,通过中介者来间接完成与其他同事对象的通信。
2.2 中介者模式的实现
//抽象中介者
/**
* 抽象中介者
*/
public abstract class Mediator {
public abstract void componentChanged(Component c);
}
//具体中介者
/**
* 组件的具体中介者
*/
public class ComponentMediator extends Mediator{
private ButtonComponent button;
private ListComponent list;
private ComboBoxComponent comboBox;
private TextBoxComponent textBox;
@Override
public void componentChanged(Component c) {
if(c == button){
System.out.println("---单击增加按钮---");
list.update();
comboBox.update();
textBox.update();
}else if (c == list){
System.out.println("---从列表框选择客户---");
comboBox.select();
textBox.setText();
}else if(c == comboBox){
System.out.println("---从组合框选择客户---");
comboBox.select();
textBox.setText();
}
}
public void setButton(ButtonComponent button) {
this.button = button;
}
public void setList(ListComponent list) {
this.list = list;
}
public void setComboBox(ComboBoxComponent comboBox) {
this.comboBox = comboBox;
}
public void setTextBox(TextBoxComponent textBox) {
this.textBox = textBox;
}
}
//抽象同事类
/**
* 抽象组件类
*/
public abstract class Component {
private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void changed(){
mediator.componentChanged(this);
};
public abstract void update();
}
//具体同事类
/**
* 按钮类,具体同事类
*/
public class ButtonComponent extends Component{
@Override
public void update() {
//按钮不产生响应
}
}
/**
* 列表框类,具体同事类
*/
public class ListComponent extends Component{
@Override
public void update() {
System.out.println("列表框增加一项:关羽");
}
public void select(){
System.out.println("列表框选中一项:张飞");
}
}
/**
* 组合框,具体同事类
*/
public class ComboBoxComponent extends Component{
@Override
public void update() {
System.out.println("组合框增加一项:赵云");
}
public void select(){
System.out.println("组合框选中项:刘备");
}
}
/**
* 文本框类,具体同事类
*/
public class TextBoxComponent extends Component{
@Override
public void update() {
System.out.println("客户信息增加成功后文本框清空。");
}
public void setText(){
System.out.println("文本框显示:诸葛亮");
}
}
//客户端
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 一个客户信息管理模块,在界面组件之间存在较为复杂的交互关系:
* 如果删除一个客户,则将从客户列表List中删掉对应的项,客户选择组合框中的客户名称也将对应的减少一个;
* 如果增加一个客户,则将从客户列表List中增加一个客户,并且组合框中也将增加一项。
* 请使用中介者模式模拟该功能模块。
*/
//定义终结者对象
ComponentMediator mediator;
mediator = new ComponentMediator();
//定义同事对象
ButtonComponent button = new ButtonComponent();
ListComponent list = new ListComponent();
ComboBoxComponent comboBox = new ComboBoxComponent();
TextBoxComponent textBox = new TextBoxComponent();
button.setMediator(mediator);
list.setMediator(mediator);
comboBox.setMediator(mediator);
textBox.setMediator(mediator);
mediator.setButton(button);
mediator.setList(list);
mediator.setComboBox(comboBox);
mediator.setTextBox(textBox);
//动作
button.changed();
System.out.println("-----------");
list.changed();
System.out.println("-----------");
comboBox.changed();
}
}
三、中介者模式的优缺点和适用环境
3.1 中介者模式的优点
- 简化了对象之间的交互;
- 可将各同事对象解耦
- 可以减少子类的生成
3.2 中介者模式的缺点
- 在具体中介者类中包含了大量同事对象之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
3.3 中介者模式的适用环境
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解;
- 一个对象由于引用类其他很多对象并且直接和这些对象通信,导致难以复用该对象;
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git