思考中介者模式
当多个类(对象)耦合严重时,通过中介者模式创建一个中介者,多个类不直接交互了,变成和中介者进行交互,松散耦合
1.中介者模式的本质
中介者模式的本质:封装交互。
中介者模式的目的,就是用来封装多个对象的交互,这些交互的处理多在中介者对象里面实现。因此中介对象的复杂程度,就取决于它封装的交互的复杂程度。
只要是实现封装对象之间的交互功能,就可以应用中介者模式,而不必过于拘泥于中介者模式本身的结构。标准的中介者模式限制很多,导致能完全按照标准使用中介者模式的地方并不是很多,而且多集中在界面实现上。只要本质不变,稍稍变形一下,简化一下,或许能更好地使用中介者模式。
2.何时选用中介者模式
建议在以下情况时选用中介者模式。
- 如果一组对象之间的通信方式比较复杂,导致相互依赖、结构混乱,可以采用中介者模式,把这些对象相互的交互管理起来,各个对象都只需要和中介者交互,从而使得各个对象松散耦合,结构也更清晰易懂。
- 如果一个对象引用很多的对象,并直接跟这些对象交互,导致难以复用该对象,可以采用中介者模式,把这个对象跟其他对象的交互封装到中介者对象里面,这个对象只需要和中介者对象交互就可以了。
3.优缺点
中介者模式的优点。
-
松散耦合
中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互不依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一发而动全身”了。 -
集中控制交互
多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那就扩展中介者对象,而各个同事类不需要做修改。 -
多对多变成一对多
没有使用中介者模式的时候,同事对象之间的关系通常是多对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成了双向的一对多,这会让对象的关系更容易理解和实现。
中介者模式的缺点。
中介者模式的一个潜在缺点是,过度集中化。如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到中介者的时候,会导致中介者对象变得十分复杂,而且难于管理和维护。
4.实现
各个类互相调用,耦合严重,更改一出功能就可能影响其他地方
加上主板以后,只需要和主板沟通,集中控制
中介类:主板
同事类:Cd、Cpu、声卡
流程:
1.读取cd数据,通知主板
2.主板通知cpu处理数据
3.cpu处理完数据,通知主板
4.主板将数据交给声卡
同事类
/**
* @description:三个同事类都要持有中介者对象,提出一个抽象类
*/
@Getter
@AllArgsConstructor
public abstract class Colleague {
//各个类要通知中介者对象,所有要持有中介者对象
//中介者对象
private MainBoardMediator mediator;
}
/**
* @description:Cd同事类
*/
public class CdColleagues extends Colleague{
//数据
public String data="";
public String getData() {
return data;
}
public CdColleagues(MainBoardMediator mediator) {
super(mediator);
}
public void readCD(){
this.data=" 你好啊 ";
this.getMediator().read(this);
}
}
/**
* @description:Cpu同事类
*/
public class CpuColleagues extends Colleague{
//声音数据
public String soundDate="";
public String getSoundDate() {
return soundDate;
}
public CpuColleagues(MainBoardMediator mediator) {
super(mediator);
}
public void execute(String data){
soundDate = data.trim();
this.getMediator().noticeSound(this);
}
}
/**
* @description:声卡同事类
*/
public class SoundColleagues extends Colleague{
public SoundColleagues(MainBoardMediator mediator) {
super(mediator);
}
public void listen(String data){
System.out.println("-->声卡数据:"+data);
}
}
中介者类
/**
* @description:主板(中介者)
*/
@Setter
public class MainBoardMediator {
//中介者负责协调各个对象,所以要持有这些对象
//cpu对象
private CpuColleagues cpu=null;
//cd对象
private CdColleagues cd=null;
//声卡对象
private SoundColleagues sound=null;
/**
* 通知cpu处理数据
*/
public void read(Colleague colleague){
//cd数据
CdColleagues cdColleagues=(CdColleagues)colleague;
//主板通知cpu处理
cpu.execute(cdColleagues.getData());
}
/**
* 通知声卡播放声音
*/
public void noticeSound(Colleague colleague){
CpuColleagues cpuColleagues=(CpuColleagues)colleague;
//主板通知声卡接收数据
sound.listen(cpuColleagues.getSoundDate());
}
}
测试类
/**
* @description:测试类
*/
public class Client {
public static void main(String[] args) {
MainBoardMediator mediator = new MainBoardMediator();
//同事类持有中介者类
CdColleagues cdColleagues = new CdColleagues(mediator);
CpuColleagues cpuColleagues = new CpuColleagues(mediator);
SoundColleagues soundColleagues = new SoundColleagues(mediator);
//中介者类持有同事对象
mediator.setCd(cdColleagues);
mediator.setCpu(cpuColleagues);
mediator.setSound(soundColleagues);
//cd读取数据
cdColleagues.readCD();
}
}
类图