嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:
中介者模式是一种软件设计模式,它允许定义一个中间对象(中介者),来协调一组对象之间的交互。通过将一组对象之间的交互抽象化到一个单独的对象中,使得各个对象不必直接交互,而只与中介者发生交互,从而使原本复杂的多对多的关系变成相对简单的单对单或一对多的关系。
中介者模式(Mediator Pattern)包含以下四个核心角色:
中介者模式的目的是通过引入中介者来简化对象之间的复杂交互,将多对多的复杂关系转化为相对简单的一对多关系。中介者的职责是进行结构性中转作用和协调行为。结构性中转作用是指各个同事对象不再需要显式地引用其他同事,当需要和其他同事进行通信时,可通过中介者来实现间接调用。协调行为是指中介者可以更进一步地对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑对同事的请求进行进一步处理。
// 抽象中介者
public abstract class Mediator {
public abstract void register(Colleague colleague);
public abstract void relay(Colleague cl); //转发
}
public class ConcreteMediator extends Mediator {
private List colleagues = new ArrayList();
public void register(Colleague colleague) {
if (!colleagues.contains(colleague)) {
colleagues.add(colleague);
colleague.setMedium(this);
}
}
public void relay(Colleague cl) {
for (Colleague ob : colleagues) {
if (!ob.equals(cl)) {
((Colleague) ob).receive();
}
}
}
}
//抽象同事类
public abstract class Colleague {
protected Mediator mediator;
public void setMedium(Mediator mediator) {
this.mediator = mediator;
}
public abstract void receive();
public abstract void send();
}
//具体同事类
public class ConcreteColleague1 extends Colleague {
public void receive() {
System.out.println("具体同事类1收到请求。");
}
public void send() {
System.out.println("具体同事类1发出请求。");
mediator.relay(this); //请中介者转发
}
}
//具体同事类
class ConcreteColleague2 extends Colleague {
public void receive() {
System.out.println("具体同事类2收到请求。");
}
public void send() {
System.out.println("具体同事类2发出请求。");
mediator.relay(this); //请中介者转发
}
}
public class MediatorPattern {
public static void main(String[] args) {
Mediator md = new ConcreteMediator();
Colleague c1, c2;
c1 = new ConcreteColleague1();
c2 = new ConcreteColleague2();
md.register(c1);
md.register(c2);
c1.send();
System.out.println("-------------");
c2.send();
}
}
通过上面的介绍,相信对中介者模式已经有了一个大概的印象了,这里再模拟一个业务场景来重点理解一下,中介者模式中各角色之间是如何交互的.
以前在农村的村部都会有一个大喇叭,上级有什么通知啥的、或者是谁家有个啥喜事都是通过个大喇叭通知给全体村民的,这里的大喇叭实际上就相当于一个中介者的角色,村长可以用来通知上级的重要指示,其他村民也可用来通知自己的喜事.如果使用中介者模式写一段程序来模拟这个过程,应该怎么实现呢?
1、声明一个抽象的喇叭接口,即抽象中介者角色,定义两个抽象方法:注册喇叭的使用者、播放消息;
/**
* 抽象喇叭
*/
public interface Horn {
/**
* 注册使用者
* @param villager
*/
void register(Villager villager);
/**
* 播放消息
* @param msg
*/
void play(Villager villager,String msg);
}
2、声明一个具体的喇叭类,即具体的中介者角色,实现抽象喇叭接口,实现其中定义的抽象方法;
/**
* 具体的喇叭
*/
public class ConcreteHorn implements Horn{
private List list=new ArrayList<>();
@Override
public void register(Villager villager) {
list.add(villager);
villager.setHorn(this);
}
@Override
public void play(Villager villager,String msg) {
for (Villager obj : list) {
if (!obj.equals(villager)) {
obj.receive(msg);
}
}
}
}
3、声明一个抽象的村民类,即抽象同事类,每一个村民都有权利使用喇叭,因此在抽象村民类内部定义一个喇叭属性,另外定义两个抽象方法:用于接受其他村民发的消息和自己向其他村民发消息;
/**
* 抽象村民
*/
public abstract class Villager {
protected Horn horn;
public void setHorn(Horn horn) {
this.horn = horn;
}
/**
* 发消息
* @param msg
*/
public abstract void send(String msg);
/**
* 收到消息
* @param msg
*/
public abstract void receive(String msg);
}
4、声明具体的村民类,即具体的同事类,这里声明两个作为村民代表,一个是村长类,另一个是村民代表张三类,继承抽象的村民类,并实现抽象村民类中的两个抽象方法;
/**
* 村长
*/
public class VillageHead extends Villager{
@Override
public void send(String msg) {
this.horn.play(this,msg);
}
@Override
public void receive(String msg) {
System.out.println("村长收到消息:"+msg);
}
}
/**
* 张三
*/
public class ZhangSan extends Villager{
@Override
public void send(String msg) {
this.horn.play(this,msg);
}
@Override
public void receive(String msg) {
System.out.println("张三收到消息:"+msg);
}
}
/**
* 其他村民
*/
public class OtherVillager extends Villager{
@Override
public void send(String msg) {
this.horn.play(this,msg);
}
@Override
public void receive(String msg) {
System.out.println("其他村民收到消息:"+msg);
}
}
5、编写客户端业务,模拟村长给村民发送上级通知、和张三给其他村民发布喜讯通知;
public class Client {
public static void main(String[] args) {
Horn horn=new ConcreteHorn();
Villager zhangsan=new ZhangSan();
Villager otherVillager=new OtherVillager();
Villager villageHead=new VillageHead();
horn.register(zhangsan);
horn.register(otherVillager);
horn.register(villageHead);
zhangsan.send("大家好,俺是村东头张三!俺娃考上县城第一中学了,晚上都到我家喝酒!");
System.out.println("-------------");
villageHead.send("各位村民注意了!上级调配的种子化肥已到村部,各家速来领取!");
}
}
生活水平提高了,村里喇叭年久失修,也不太好用了,于是村民一致支持在村头广场上建个LED大屏,用途和以前的喇叭一样,也是用来方便传递消息,晚上还插放个新闻联播。怎么实现呢?很简单重新定义LED类,实现抽象喇叭接口,然后再调整一个客户端业务就可以了;这样村里就有两套传递消息的机制了,互不影响;
public class LED implements Horn{
private List list=new ArrayList<>();
@Override
public void register(Villager villager) {
this.list.add(villager);
villager.setHorn(this);
}
@Override
public void play(Villager villager, String msg) {
for (Villager obj : list) {
if (!obj.equals(villager)) {
obj.receive(msg);
}
}
}
}
public class Client {
public static void main(String[] args) {
Villager zhangsan=new ZhangSan();
Villager otherVillager=new OtherVillager();
Villager villageHead=new VillageHead();
Horn horn=new LED();
horn.register(zhangsan);
horn.register(otherVillager);
horn.register(villageHead);
villageHead.send("村民们注意了!村里新修的大屏今天正式投入使用了,晚上放电影,铁道游击队!");
}
}
那么如果村里有新村民迁入了,应该怎么扩展,是不是也很简单了?
中介者模式适用于具有以下特征的业务场景:
中介者模式的优点在于:
然而,中介者模式也有一些缺点:
中介者模式是一种软件设计模式,它的目的是将一组对象之间的交互抽象化到一个单独的对象中,使得各个对象不必直接交互,而只与这个中间对象发生交互。这种模式可以帮助我们减少类之间的依赖关系,实现类之间的解耦,并简化复杂的交互关系。