当多个类(对象)耦合严重时,通过中介者模式创建一个中介者,多个类不直接交互了,变成和中介者进行交互,松散耦合
中介者模式的本质:封装交互。
中介者模式的目的,就是用来封装多个对象的交互,这些交互的处理多在中介者对象里面实现。因此中介对象的复杂程度,就取决于它封装的交互的复杂程度。
只要是实现封装对象之间的交互功能,就可以应用中介者模式,而不必过于拘泥于中介者模式本身的结构。标准的中介者模式限制很多,导致能完全按照标准使用中介者模式的地方并不是很多,而且多集中在界面实现上。只要本质不变,稍稍变形一下,简化一下,或许能更好地使用中介者模式。
建议在以下情况时选用中介者模式。
中介者模式的优点。
松散耦合
中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互不依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一发而动全身”了。
集中控制交互
多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那就扩展中介者对象,而各个同事类不需要做修改。
多对多变成一对多
没有使用中介者模式的时候,同事对象之间的关系通常是多对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成了双向的一对多,这会让对象的关系更容易理解和实现。
中介者模式的缺点。
中介者模式的一个潜在缺点是,过度集中化。如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到中介者的时候,会导致中介者对象变得十分复杂,而且难于管理和维护。
各个类互相调用,耦合严重,更改一出功能就可能影响其他地方
加上主板以后,只需要和主板沟通,集中控制
中介类:主板
同事类: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();}
}
类图