1.什么是中介者模式?
中介者模式:定义一个对象来封装一系列对象的交互。中介者模式使各对象之间不需要显式地相互引用,从而使其耦合松散,而且用户可以独立的改变他们之间的交互。
说人话就是:降低原有对象之间的复杂引用关系。
举个例子:QQ给10个人发同样文件,需要加10次好友,发10次。拉个群,发一次就行。这个群相当于就是中介者。
2.中介者模式结构
(1)Mediator(抽象中介者):它定义了一个接口,该接口用于与各同事对象之间进行通信
(2)ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用
(3)Colleague(抽象同事类):它定义各个同事类共有的方法,并声明了一些抽象方法供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用与中介者通信
(4)ConcreteColleague(具体同事类):他是抽象同事类的子类,每一个同事对象在需要和其他同事对象通信时先与中介者通信,通过中介者间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
3.中介者模式实现
(1)抽象中介者类
/**
* 抽象中介者类
*/
public abstract class Mediator {
protected ArrayList colleagues = new ArrayList();//用于存储同事对象
//注册方法,用于增加同事对象
public void register(Colleague colleague){
colleagues.add(colleague);
}
//声明抽象的业务方法
public abstract void operation();
}
(2)具体中介者类代码
/**
* 具体中介者类代码
*/
public class ConcreteMediator extends Mediator {
//实现业务方法,封装同事之间的调用
@Override
public void operation() {
//...
((Colleague)(colleagues.get(0))).method1();//通过中介者调用同事类的方法
//...
}
}
(3)抽象同事类
/**
* 抽象同事类
*/
public abstract class Colleague {
protected Mediator mediator;//维持一个抽象中介者的引用
public Colleague(Mediator mediator){
this.mediator = mediator;
}
public abstract void method1();//声明自身方法,处理自己的行为
//定义依赖方法,与中介者进行通信
public void method2(){
mediator.operation();
}
}
(4)具体同事类
/**
* 具体同事类
*/
public class ConcreteColleague extends Colleague {
public ConcreteColleague(Mediator mediator) {
super(mediator);
}
//实现自身方法
@Override
public void method1() {
}
}
4.中介者模式实例——增删用户,用户列表以及用户信息跟着进行增删
(1)抽象中介者类
/**
* 抽象中介者类
*/
public abstract class Mediator {
public abstract void componentChanged(Component c);
}
(2)具体中介者类
/**
* 具体中介者类
*/
public class ConcreteMediator extends Mediator {
//维持对各个同事对象的引用
public Button addButton;
public List list;
public TextBox userNameTextBox;
public ComboBox cb;
@Override
public void componentChanged(Component c) {
//单机按钮
if(c == addButton){
System.out.println("--单机增加按钮--");
list.update();
cb.update();
userNameTextBox.update();
}else if(c == list){//从列表框选择客户
System.out.println("--从列表框选择客户--");
cb.select();
userNameTextBox.setText();
}else if(c == cb){//从组合框选择客户
System.out.println("--从组合框选择客户--");
cb.select();
userNameTextBox.setText();
}
}
}
(3)抽象组件类,充当抽象同事类
/**
* 抽象组件类,充当抽象同事类
*/
public abstract class Component {
protected Mediator mediator;
public void setMediator(Mediator mediator){
this.mediator = mediator;
}
//转发调用
public void changed(){
mediator.componentChanged(this);
}
public abstract void update();
}
(4)按钮类,充当具体同事类
/**
* 按钮类,充当具体同事类
*/
public class Button extends Component {
@Override
public void update() {
//按钮不产生相应
}
}
(5)列表框类,充当具体同事类
/**
* 列表框类,充当具体同事类
*/
public class List extends Component {
@Override
public void update() {
System.out.println("列表框增加一条:张无忌");
}
public void select(){
System.out.println("列表框选中项:小龙女");
}
}
(6)组合框类,充当具体同事类
/**
* 组合框类,充当具体同事类
*/
public class ComboBox extends Component {
@Override
public void update() {
System.out.println("组合框增加一项:张无忌");
}
public void select(){
System.out.println("列表框选中项:小龙女");
}
}
(7)文本框类,充当具体同事类
/**
* 文本框类,充当具体同事类
*/
public class TextBox extends Component {
@Override
public void update() {
System.out.println("客户信息增加成功后文本框清空");
}
public void setText(){
System.out.println("文本框显示:小龙女");
}
}
(8)客户端类
public class Client {
public static void main(String[] args) {
//定义中介者对象
ConcreteMediator mediator;
mediator = new ConcreteMediator();
//定义同事对象
Button addBT = new Button();
List list = new List();
ComboBox cb = new ComboBox();
TextBox userNameTb = new TextBox();
addBT.setMediator(mediator);
list.setMediator(mediator);
cb.setMediator(mediator);
userNameTb.setMediator(mediator);
mediator.addButton = addBT;
mediator.list = list;
mediator.cb = cb;
mediator.userNameTextBox = userNameTb;
addBT.changed();
System.out.println("--------");
list.changed();
}
}
(9)输出结果及路径
5.扩展中介者与同事类
上述实例如果需要新增一个Label,无需修改ConcreteMediator,而是增加一个子类,然后覆盖componentChanged()方法。原来组件类代码无需变动,客户端代码需要少许修改。
(1)新增同事类
public class Label extends Component {
@Override
public void update() {
System.out.println("文本标签内容梗概,客户信息总数加1");
}
}
(2)具体中介者抽出子类
public class SubConcreteMediator extends ConcreteMediator {
//增加对Label的引用
public Label label;
public void componentChanged(Component c) {
//单机按钮
if(c == addButton){
System.out.println("--单机增加按钮--");
list.update();
cb.update();
userNameTextBox.update();
//文本标签更新
label.update();
}else if(c == list){//从列表框选择客户
System.out.println("--从列表框选择客户--");
cb.select();
userNameTextBox.setText();
}else if(c == cb){//从组合框选择客户
System.out.println("--从组合框选择客户--");
cb.select();
userNameTextBox.setText();
}
}
}
(3)修改客户端
public class Client {
public static void main(String[] args) {
// //定义中介者对象
// ConcreteMediator mediator;
// mediator = new ConcreteMediator();
//用新增具体中介者定义中介者对象、
SubConcreteMediator mediator;
mediator = new SubConcreteMediator();
//定义同事对象
Button addBT = new Button();
List list = new List();
ComboBox cb = new ComboBox();
TextBox userNameTb = new TextBox();
Label label = new Label();
addBT.setMediator(mediator);
list.setMediator(mediator);
cb.setMediator(mediator);
userNameTb.setMediator(mediator);
label.setMediator(mediator);
mediator.addButton = addBT;
mediator.list = list;
mediator.cb = cb;
mediator.userNameTextBox = userNameTb;
mediator.label = label;
addBT.changed();
System.out.println("--------");
list.changed();
}
}
6.中介者模式的优缺点
优:
(1)简化了对象之间的交互
(2)将各同事对象解耦
(3)减少子类生成
缺:
系统复杂
7.中介者模式适用环境
(1)系统中对象之间存在复杂引用关系
(2)一个对象由于引用了其他很多对象,并且直接和这些对象通信。导致该对象难以复用
(3)想通过一个中间类来封装多个类中的行为,而又不想有太多的子类