中介者模式概述
新增页面的同时清空内容,新增列表,按钮不可用..点击按钮的同时清空页面内容,更新列表...各个组件相互依赖,存在多对多的关联,将会导致系统非常复杂,要新增一个新的组件会变得异常艰难.在网状结构中,几乎每个对象都需要与其他对象发生相互作用,而这种相互作用表现为一个对象与另外一个对象的直接耦合,这将导致一个过度耦合的系统.这个时候引入一个第三方的中介,将网状结构转变成星型结构.就可以将对象间的耦合变成对象与中介之间的调用,降低系统的耦合程度,这就是中介者模式的意义所在.
如图
星型结构
中介者模式定义
用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
中介者模式的优缺点
优点
- 简化了对象之间的交互,它用中介者和组件的一对多交互代替了原来组件之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
- 有利于各组件之间的松耦合,我们可以独立的改变和复用每一个组件和中介者,增加新的中介者和新的组件类都比较方便,更好地符合“开闭原则”。
缺点
- 在具体中介者类中包含了大量组件之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
适用场景
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
UML图
image示例
有一套图形界面类库。该类库需要包含若干预定义的窗格(Pane)对象,例如TextPane、ListPane、GraphicPane等,窗格之间不允许直接引用。基于该类库的应用由一个包含一组窗格的窗口(Window)组成,窗口需要协调窗格之间的行为。试采用中介者模式设计该系统。
抽象的Window
public abstract class AbstractWindow {
public abstract void componentChanged(Pane pane);
}
抽象窗格对象
public abstract class Pane {
protected AbstractWindow abstractWindow;
public void setAbstractWindow(AbstractWindow abstractWindow) {
this.abstractWindow = abstractWindow;
}
public void changed(){
abstractWindow.componentChanged(this);
}
public abstract void update();
}
具体组件
public class TextPane extends Pane {
@Override
public void update() {
System.out.println("文本刷新");
}
}
public class ListPane extends Pane {
@Override
public void update() {
System.out.println("列表刷新");
}
public void selected(){
System.out.println("列表选中");
}
}
public class GridPane extends Pane {
@Override
public void update() {
System.out.println("网格刷新");
}
}
public class ButtonPane extends Pane {
@Override
public void update() {
System.out.println("按钮变色");
}
}
中介类
public class ConcreteWindow extends AbstractWindow {
public TextPane textPane;
public GridPane gridPane;
public ListPane listPane;
public ButtonPane buttonPane;
@Override
public void componentChanged(Pane pane) {
if (pane == textPane) {
//文本框改变,按钮变色,列表选中
buttonPane.update();
listPane.selected();
} else if (pane == gridPane) {
//网格改变,列表刷新
listPane.update();
} else if (pane == listPane) {
//列表改变,文本刷新
textPane.update();
} else if (pane == buttonPane) {
//按钮点击更新三个控件的状态
textPane.update();
gridPane.update();
listPane.update();
}
}
}
调用
ConcreteWindow concreteWindow = new ConcreteWindow();
ButtonPane buttonPane = new ButtonPane();
TextPane textPane = new TextPane();
ListPane listPane = new ListPane();
GridPane gridPane = new GridPane();
concreteWindow.buttonPane = buttonPane;
concreteWindow.textPane = textPane;
concreteWindow.listPane = listPane;
concreteWindow.gridPane = gridPane;
buttonPane.setAbstractWindow(concreteWindow);
textPane.setAbstractWindow(concreteWindow);
listPane.setAbstractWindow(concreteWindow);
gridPane.setAbstractWindow(concreteWindow);
buttonPane.changed();
输出
文本刷新
网格刷新
列表刷新
网友评论