中介者模式又叫調(diào)解者模式或調(diào)停者模式乏悄,是行為型設(shè)計(jì)模式之一。
生活中的中介者的作用就是連接兩方的一個橋梁恳不,比如房產(chǎn)中介纲爸,買房的只需跟中介打交道,然后買房的也跟著中介打交道妆够,
沒有中介的時(shí)候是這樣的:
每個買房的和賣房的都要和很多對方打交道,有了新的買房人负蚊,這些賣房的都得知道才能去和他聯(lián)系神妹。
有了中介者之后:
所有買房的和賣房的都只需要跟中介者一個人打交道,買房的不需要知道賣房的是什么人家妆,有多少賣房的等等鸵荠。都省事了很多。
定義
通過中介者包裝一系列對象的交互伤极,使得這些對象不必相互顯式引用蛹找,從而使它們可以松散耦合姨伤。
當(dāng)某些對象之間的作用發(fā)生變化是,不會立即影響其他對象間的作用庸疾,保證這些作用協(xié)議彼此獨(dú)立的變化乍楚。
中介者模式將多對多的相互作用轉(zhuǎn)化為一堆多的相互作用。
使用場景
- 多個對象之間的交互操作很多届慈,每個對象的行為都依賴批次徒溪,形成網(wǎng)狀的多對多結(jié)構(gòu),為了防止修改一個對象時(shí)要修改很多其他對象金顿,可以用中介者模式臊泌。
UML
- Mediator: 抽象的中介者角色,定義了同事對象到中介者的接口揍拆。
- ConcreteMediator:具體的中介者角色渠概,從具體的同事對象接收消息,同時(shí)向具體的同事對象發(fā)出命令嫂拴。
- Colleague:抽象同事類角色播揪,定義了中介者對象的接口,只知道中介而不知道其他同事對象顷牌。
- ConcreteColleagueA剪芍,B:具體的同事類角色,每個具體同事類都知道本身在小范圍內(nèi)的行為窟蓝,而不知道他在大范圍中的行為疮跑。
模板代碼:
抽象的中介者:
public interface Mediator {
void change();
}
具體的中介者:
public class ConcreteMediator implements Mediator {
public ConcreteColleagueA concreteColleagueA;
public ConcreteColleagueB concreteColleagueB;
public void setConcreteColleagueA(ConcreteColleagueA concreteColleagueA) {
this.concreteColleagueA = concreteColleagueA;
}
public void setConcreteColleagueB(ConcreteColleagueB concreteColleagueB) {
this.concreteColleagueB = concreteColleagueB;
}
@Override
public void change() {
concreteColleagueA.action();
concreteColleagueB.action();
}
}
抽象的同事:
public abstract class Colleague {
public Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void action();
}
具體的同事:
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
System.out.println("交給中介做A的事情");
}
}
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
@Override
public void action() {
System.out.println("交給中介做B的事情");
}
}
簡單實(shí)現(xiàn)
以電腦為例子。CPU苟跪,顯卡亲配,內(nèi)存等零件的交互都是通過主板實(shí)現(xiàn)的,而且每個零件只需要做好自己的工作谁帕,不需要知道其他零件是什么峡继。所以主板可以作為他們的中介者。
抽象的中介者:
public abstract class Mediator {
public abstract void change(Colleague colleague);
}
具體的中介者匈挖,主板:
public class MainBoard extends Mediator {
private CDDevice cdDevice;
private CPU cpu;
private GraphicsCard graphicsCard;
private SoundCard soundCard ;
@Override
public void change(Colleague colleague) {
if (colleague==cdDevice){
handleCD((CDDevice) colleague);
}
if (colleague==cpu){
handleCPU((CPU) colleague);
}
}
private void handleCD(CDDevice cdDevice){
cpu.decodeData(cdDevice.read());
}
private void handleCPU(CPU cpu){
soundCard.playSound(cpu.getDataSound());
graphicsCard.vidoePlay(cpu.getDataVideo());
}
public void setCdDevice(CDDevice cdDevice) {
this.cdDevice = cdDevice;
}
public void setCpu(CPU cpu) {
this.cpu = cpu;
}
public void setGraphicsCard(GraphicsCard graphicsCard) {
this.graphicsCard = graphicsCard;
}
public void setSoundCard(SoundCard soundCard) {
this.soundCard = soundCard;
}
}
抽象的零件:
public abstract class Colleague {
public Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
}
具體的零件:
public class CPU extends Colleague {
private String dataVideo,dataSound;
public CPU(Mediator mediator) {
super(mediator);
}
public String getDataVideo(){
return dataVideo;
}
public String getDataSound() {
return dataSound;
}
//解析數(shù)據(jù)碾牌,分割音頻和視頻
public void decodeData(String data){
String[] tmp = data.split(",");
dataVideo=tmp[0];
dataSound=tmp[1];
mediator.change(this);
}
}
public class CDDevice extends Colleague {
private String data;
public CDDevice(Mediator mediator) {
super(mediator);
}
public String read(){
return data;
}
public void load(){
data="視頻數(shù)據(jù)儡循,音頻數(shù)據(jù)";
mediator.change(this);
}
}
public class GraphicsCard extends Colleague {
public GraphicsCard(Mediator mediator) {
super(mediator);
}
public void vidoePlay(String data){
System.out.println("播放視頻:"+data);
}
}
public class SoundCard extends Colleague {
public SoundCard(Mediator mediator) {
super(mediator);
}
public void playSound(String data){
System.out.println("播放音頻:"+ data);
}
}
總結(jié)
在面向?qū)ο缶幊讨胁奥穑粋€類必然會與其他類產(chǎn)生依賴關(guān)系,當(dāng)依賴關(guān)系錯綜復(fù)雜時(shí)择膝,可以考慮用中介者模式進(jìn)行解耦誓琼。
優(yōu)點(diǎn)
- 降低類的關(guān)系復(fù)雜度,將多對多轉(zhuǎn)化成一對多,實(shí)現(xiàn)解耦腹侣。
- 符合迪米特原則(最少知識原則)
缺點(diǎn)
- 中介者要做很多事叔收,會變得龐大且難以維護(hù)。
- 如果本來關(guān)系并不復(fù)雜傲隶,那么使用中介者可能會讓關(guān)系變得更復(fù)雜饺律。