模式定义定义了一个中介对象来封装一系列对象之间的交互,使得原有对象之间的耦合松散,它们之间的交互可以独立改变。中介模式也称中介模式,是迪米特定律的典型应用。得墨忒耳法则(LoD),又称最少知识原则(LKP),起源于1987年美国东北大学一项名为得墨忒耳的研究项目。由IanHolland提出,由Booch推广,Booch是其创始人之一UML,后来广为人知的是在经典书籍《程序员修炼之道》(ThePragmaticProgrammer)中提到的。得墨忒尔定律的定义是:只与你的直系朋友交谈,不与“陌生人”交谈(Talkonlytoyourtinyfriendsandnottostrangers)。其含义是:如果两个软件实体不需要直接通信,则不应有直接的相互调用,调用可以由第三方转发。其目的是降低类之间的耦合度,提高模块的相对独立性。迪米特定律中的“朋友”指的是:当前对象本身、当前对象的成员对象、当前对象创建的对象、当前对象的方法参数等。这些对象关联、聚合或组合当前对象,并且可以是直接访问这些对象的方法。模板实现如下:packagecom.niuh.designpattern.mediator.v1;importjava.util.ArrayList;importjava.util.List;/***
*MediatorPattern*
*/publicclassMediatorPattern{publicstaticvoidmain(String[]args){Mediatormd=newConcreteMediator();Colleaguec1,c2;c1=newConcreteColleague1();c2=newConcreteColleague2();md.register(c1);md.register(c2);c1.send();System.出去。println("==============");c2.send();}}//抽象中介abstractclassMediator{publicabstractvoidregister(Colleaguecolleague);publicabstractvoidrelay(Colleaguecl);//转发}//具体中介类ConcreteMediatorextendsMediator{privateList
colleagues=newArrayList();publicvoidregister(Colleaguecolleague){if(!colleagues.contains(colleague)){colleagues.add(colleague);colleague.setMedium(this);}}publicvoidrelay(Colleaguecl){for(Colleagueob:colleagues){if(!ob.equals(cl)){((Colleague)ob).receive();}}}}//抽象同事类abstractclassColleague{protectedMediatormediator;publicvoidsetMedium(Mediatormediator){this.mediator=mediator;}publicabstractvoidreceive();publicabstractvoidsend();}//具体同事类classConcreteColleague1extendsColleague{publicvoidreceive(){System.out.println("具体同事类1接收请求");}publicvoidsend(){System.out.println("特定同事类1发送请求。");mediator.relay(this);//请转发中介者}}//特定同事类classConcreteColleague2extendsColleague{publicvoidreceive(){System.out.println("特定同事2类收到请求。");}publicvoidsend(){System.out.println("特定同事2类发送请求。");mediator.relay(this);//请转发中介}}结果如下:具体Colleagueclass1提出请求。特定同事类2接收请求。具体同事类2提出要求。特定同事类1接收请求。待解决的问题对象之间存在着大量的关联,必然导致系统结构非常复杂。同时,如果一个对象发生了变化,我们也需要跟踪关联的对象并做出相应的处理。.模式构成中介模式的实现关键在于找出“中介”。实例说明实例概述用中介模型编写一个“北京房产交易平台”程序。分析:北京房产交易平台是“房产中介公司”为“卖家客户”和“买家客户”提供的信息交流平台,更适合采用中介模式变现。使用步骤第一步:定义一个中介公司(Medium)接口,它是一个抽象的中介,包括客户注册方法register(Customermember)和信息转发方法relay(Stringfrom,Stringad);interfaceMedium{//客户注册voidregister(Customermember);//转发voidrelay(Stringfrom,Stringad);}第二步:定义一个北京房产中介(EstateMedium)公司,它是一个具体的中介类,它包含一个List对象,存储客户信息,并在公司实现中介抽象方法。//具体中介:房产中介classEstateMediumimplementsMedium{privateListmembers=newArrayList();publicvoidregister(Customermember){if(!members.contains(member)){members.add(member);member.setMedium(this);}}publicvoidrelay(Stringfrom,Stringad){for(Customerob:members){Stringname=ob.getName();if(!name.equals(from)){((Customer)ob).receive(from,ad);}}}}第三步:定义一个客户(Qistomer)类,它是一个抽象类colleague类,里面包含中介的对象,以及发送信息的send(Stringad)方法和receive(Stringfrom,Stringad)方法接口,因为本程序是窗口程序,所以该类继承了JPmme类,并实现动作事件处理方法actionPerformed(ActionEvente)。//抽象同事类:客户abstractclassCustomerextendsJFrameimplementsActionListener{privatestaticfinallongserialVersionUID=-7219939540794786080L;protectedMediummedium;protectedStringname;JTextFieldSentText;JTextAreaReceiveArea;publicCustomer(Stringname){super(name);this.name=name;}voidClientWindow(intx,inty){Containercp;JScrollPanesp;JPanelp1,p2;cp=this.getContentPane();SentText=newJTextField(18);ReceiveArea=newJTextArea(10,18);ReceiveArea.setEditable(false);p1=newJPanel();p1.setBorder(BorderFactory.createTitledBorder("接收内容:"));p1.add(ReceiveArea);sp=newJScrollPane(p1);cp.add(sp,BorderLayout.NORTH);p2=newJPanel();p2.setBorder(BorderFactory.createTitledBorder("发送内容:"));p2.add(SentText);cp.add(p2,BorderLayout.SOUTH);SentText.addActionListener(this);this.setLocation(x,y);this.setSize(250,330);this.setResizable(false);//不能调整窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}publicvoidactionPerformed(ActionEvente){StringtempInfo=SentText.getText().trim();SentText.setText("");this.send(tempInfo);}publicStringgetName(){returnname;}publicvoidsetMedium(Mediummedium){this.medium=medium;}publicabstractvoidsend(Stringad);publicabstractvoidreceive(Stringfrom,Stringad);}第四步:定义卖方(Seller)类和买方(Buyer)类,它们是客户(Customer)类的具体同事类和子类,他们在父类方法通过中介类交换信息//具体同事类:Seller类SellerextendsCustomer{privatestaticfinallongserialVersionUID=-1443076716629516027L;publicSeller(Stringname){super(name);ClientWindow(50,100);}publicvoidsend(Stringad){ReceiveArea.append("我(卖家)说:"+ad+"\n");//让滚动条滚动到底部ReceiveArea.setCaretPosition(ReceiveArea.getText().length());medium.relay(name,ad);}publicvoidreceive(Stringfrom,Stringad){ReceiveArea.append(from+"say:"+ad+"\n");//使滚动条滚动到底部ReceiveArea.setCaretPosition(ReceiveArea.getText().length());}}//具体同事类:buyerclassBuyerextendsCustomer{privatestaticfinallongserialVersionUID=-474879276076308825L;publicBuyer(Stringname){super(name);ClientWindow(350,100);}publicvoidsend(Stringad){ReceiveArea.append("I(buyer)said:"+ad+"\n");//滚动到底部ReceiveArea。setCaretPosition(ReceiveArea.getText().length());medium.relay(name,ad);}publicvoidreceive(Stringfrom,Stringad){ReceiveArea.append(from+"say:"+ad+"\n");//让滚动条滚动到底部ReceiveArea.setCaretPosition(ReceiveArea.getText().length());}}输出结果的优点是降低了对象之间的耦合度,使得对象易于独立复用,将对象之间的一对多关联转化为一对一关联,提高了系统的灵活性,使得系统易于维护和扩展。缺点当同事太多时,中介的责任会很大,会变得复杂和庞大,使系统难以维护。应用场景当对象之间存在复杂的网络结构关系,导致依赖关系混乱,重用困难时。当你想创建一个在多个类之间运行的对象,但又不想生成新的子类时。模式扩展在实际开发中,通常会采用以下两种方式来简化中介模式,让开发更简单。没有定义中介接口,具体的中介对象实现为单例。colleague对象不持有mediator,而是直接获取mediator对象,需要时调用。程序代码如下:packagecom.niuh.designpattern.mediator.v3;importjava.util.ArrayList;importjava.util.List;/****SimplifiedMediatorPattern*
*/publicclassSimpleMediatorPattern{publicstaticvoidmain(String[]args){Si??mpleColleaguec1,c2;c1=newSimpleConcreteColleague1();c2=newSimpleConcreteColleague2();c1.send();System.out.println("==============");c2.send();}}//简单单例中介类SimpleMediator{privatestaticSimpleMediatorsmd=newSimpleMediator();privateListcolleagues=newArrayList();privateSimpleMediator(){}publicstaticSimpleMediatorgetMedium(){return(smd);}publicvoidregister(SimpleColleaguecolleague){if(!colleagues.contains(colleague)){colleagues.add(colleague);}}publicvoidrelay(SimpleColleaguescl){for(SimpleColleagueob:colleagues){if(!ob.equals(scl)){((SimpleColleague)ob).receive();}}}}//抽象同事类interfaceSimpleColleague{voidreceive();voidsend();}//具体同事类classSimpleConcreteColleague1implementsSimpleColleague{SimpleConcreteColleague1(){SimpleMediatorsmd=SimpleMediator.getMedium();smd.register(this);}publicvoidreceive(){System.out.println("特定同事类别1:收到请求");}publicvoidsend(){SimpleMediatorsmd=SimpleMediator.getMedium();System.out.println("具体同事类1:提出请求...");smd.relay(this);//请转发中介者}}//具体同事类classSimpleConcreteColleague2implementsSimpleColleague{SimpleConcreteColleague2(){SimpleMediatorsmd=SimpleMediator.getMedium();smd.register(this);}publicvoidreceive(){System.out.println("特定同事类2:收到请求。");}publicvoidsend(){SimpleMediatorsmd=SimpleMediator.getMedium();System.out.println("具体同事类2:发送请求...");smd.relay(this);//请中介转发}}输出结果如下:具体同事类1:发送请求。..具体同事类2:收到请求。具体同事类2:发送请求...具体同事类1:接收请求。源码java.util.Timerjava.util.concurrent.Executer#execute()java.util.concurrent.ExecuterService#submit()java.lang.reflect.Method#invoke()中的应用PS:以上代码提交于Github:https://github.com/Niuh-Study/niuh-designpatterns.git