本文节选自中介模式的应用场景。在现实生活中,中介的存在是必不可少的。没有中介,我们无法与远方的朋友沟通。每个同事对象将相互引用。如果每个对象与多个对象交互,就会形成如下图所示的网络结构。从上图可以看出,各个对象都是过度耦合的,不利于信息的复用或者扩展。如果引入中介者模式,对象之间的关系就会变成星型结构,如下图所示。从上图可以看出,使用中介模式后,一个类的任何变化只会影响中介和类本身。与以前的设计不同,类中的任何更改都会导致其所有关联类的更改。这样的设计大大降低了系统的耦合度。其实在我们的日常生活中,我们每天浏览的朋友圈就是一个中介。还有就是我们看到的信息交易平台,也是中介模式的一种体现。中介者模式用于降低多个对象和类之间通信的复杂性。该模式通过提供一个中介类,将系统各级对象之间的多对多关系变为一对多关系。中介对象可以将复杂的网络结构变为以中介为中心的星型结构,以达到降低系统复杂度,提高可扩展性。如果系统的层次对象之间存在大量关联,即层次对象处于一个复杂的网络结构中,如果直接耦合通信,系统结构将变得极其复杂,当某个层次对象对象发生变化,与之紧耦合的相应层次对象也需要修改,系统难以维护。简单来说,如果多个类相互耦合形成网络结构,可以考虑使用Mediator模式进行优化。综上所述,中介模型主要适用于以下应用场景。(1)系统中对象之间存在复杂的引用关系,由此产生的相互依赖关系结构混乱,难以理解。(2)互动的公共行为。如果需要改变行为,可以添加一个新的中间类。2 Mediator模式的UML类图Mediator模式的UML类图如下图所示。3 使用中介者模式设计群聊场景假设我们要搭建一个聊天室系统,用户可以向聊天室发送消息,聊天室会向所有用户展示消息。其实就是用户发送消息和聊天室显示之间的通信过程,但是用户不能直接将消息发送到聊天室,需要先将消息发送到服务器,然后服务器再发送消息到聊天室进行显示,具体代码如下。首先创建用户类。公共类用户{私有字符串名称;私人聊天室聊天室;publicUser(Stringname,ChatRoomchatRoom){this.name=name;this.chatRoom=chatRoom;}publicvoidsendMessage(Stringmsg){this.chatRoom.showMsg(this,msg);}publicStringgetName(){返回名称;}}然后创建ChatRoom类。publicclassChatRoom{publicvoidshowMsg(Useruser,Stringmsg){System.out.println("["+user.getName()+"]:"+msg);}}最后写客户端测试代码。publicstaticvoidmain(String[]args){ChatRoomroom=newChatRoom();用户tom=newUser("Tom",room);用户jerry=newUser("Jerry",room);tom.sendMessage("嗨!我是汤姆。");jerry.sendMessage("Hello!MynameisJerry.");}运行结果如下图所示。4 中介模式在JDK源码中的应用首先看JDK中的Timer类。打开Timer结构体,我们发现Timer类中有很多schedule()重载方法,如下图所示。随意打开其中一个方法,我们发现所有的方法最终都调用了私有的schedule()方法,源码如下。publicclassTimer{...publicvoidschedule(TimerTasktask,longdelay){if(delay<0)thrownewIllegalArgumentException("负延迟。");计划(任务,System.currentTimeMillis()+延迟,0);}...privatevoidsched(TimerTasktask,longtime,longperiod){if(time<0)thrownewIllegalArgumentException("非法执行时间。");如果(Math.abs(period)>(Long.MAX_VALUE>>1))period>>=1;synchronized(queue){if(!thread.newTasksMayBeScheduled)thrownewIllegalStateException("定时器已经取消。");synchronized(task.lock){if(task.state!=TimerTask.VIRGIN)thrownewIllegalStateException("Taskalreadyscheduledorcancelled");task.nextExecutionTime=时间;task.period=period;任务tate=TimerTask.SCHEDULED;}queue.add(任务);if(queue.getMin()==task)queue.notify();}}...}而且,无论一个队列中加入了什么样的任务,我们都按顺序称这个队列中的所有对象为“同事”。同事之间的沟通是通过Timer来协调的,Timer承担了中介的作用。关注微信公众号“汤姆炸弹架构”回复“设计模式”获取完整源码。【推荐】汤姆炸弹架构:30个设计模式实战案例(附源码),挑战60W年薪不是梦技术在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号“汤姆炸弹架构”,获取更多技术干货!
