我一直在研究这两种模式之间的区别.
据我所知,facade封装了对子系统的访问,而mediator封装了组件之间的交互.
我知道子系统组件不知道外观,因为组件明显知道中介.
我目前正在使用facade来封装检索配置信息的方法,例如App.Config,存储在SQL中的用户设置,程序集信息等,以及用于在不同窗体之间导航的介体.
但是,大多数网站都指出调解员"增加了功能".这是什么意思?介体如何添加功能?
...大多数网站指出调解员"增加功能"......
的外观仅暴露出从不同的角度的现有功能.
在调解员 "增加了"功能,因为它结合了不同的现有功能来创建一个新的.
请看以下示例:
你有一个日志系统.从该日志记录系统,您可以登录到文件,套接字或数据库.
使用外观设计模式,您将"隐藏"现有功能的所有关系,这些关系位于外观所暴露的单个"界面"背后.
客户代码:
Logger logger = new Logger(); logger.initLogger("someLogger"); logger.debug("message");
实现可能涉及许多对象的交互.但最后,功能已经存在.可能"debug"方法实现如下:
执行:
class Logger { private LoggerImpl internalLogger; private LoggerManager manager; public void initLogger( String loggerName ) { this.internalLogger = manager.getLogger( loggerName ); } public void debug( String message ) { this.internalLogger.debug( message ); } }
功能已存在.外立面只隐藏它.在这个假设的情况下,LoggerManager处理正确记录器的创建,而LoggerImpl是具有"debug"方法的包私有对象.这样Facade就不会添加它只是委托给一些现有对象的功能.
另一方面,介体通过组合不同的对象来添加新功能.
相同的客户代码:
Logger logger = new Logger(); logger.initLogger("someLogger"); logger.debug("message");
执行:
class Logger { private java.io.PrintStream out; private java.net.Socket client; private java.sql.Connection dbConnection; private String loggerName; public void initLogger( String loggerName ) { this.loggerName = loggerName; if ( loggerName == "someLogger" ) { out = new PrintStream( new File("app.log")); } else if ( loggerName == "serverLog" ) { client = new Socket("127.0.0.1", 1234 ); } else if( loggerName == "dblog") { dbConnection = Class.forName()... . } } public void debug( String message ) { if ( loggerName == "someLogger" ) { out.println( message ); } else if ( loggerName == "serverLog" ) { ObjectOutputStrewam oos = new ObjectOutputStrewam( client.getOutputStream()); oos.writeObject( message ); } else if( loggerName == "dblog") { Pstmt pstmt = dbConnection.prepareStatment( LOG_SQL ); pstmt.setParameter(1, message ); pstmt.executeUpdate(); dbConnection.commit(); } } }
在此代码中,介体是包含业务逻辑的介体,用于创建记录的相应"通道"以及将日志导入该通道.调解员正在"创建"功能.
当然,有更好的方法可以使用多态实现这一点,但这里的重点是展示调解器如何通过组合现有功能来"添加"新功能(在我的示例中没有显示非常抱歉),但想象一下调解器,阅读从数据库远程主机到哪里记录,然后创建一个客户端,最后写入该客户端打印流的日志消息.这样,调解者将在不同对象之间"调解".
最后,外观是一种结构模式,即它描述了对象的组成,而中介是一种行为,即它描述了对象的交互方式.
我希望这有帮助.
我正在使用mediator添加日志文件功能.
它的工作原理如下:
Obj A告诉调解员需要完成的事情.
中介将消息发送到各种客户端对象.
Obj B执行Obj A需要的事情,并通过调解器发回适当的消息.
同时,Obj C也由调解员发送两条消息,并记录结果.这样,我们就可以从日志文件中获取用户统计信息.
Obj D也可以是错误检查器,因此如果Obj B响应Obj A的请求是不可能的,Obj D可能是向用户报告的事情.错误现在可以记录在与常规活动不同的文件中,并且可以使用一些其他方法来表示Obj A不应该真正关注的行为(嘟嘟声等等).
在相关模式下,gof说:Facade(185)与Mediator的不同之处在于它抽象对象的子系统以提供更方便的界面.它的协议是单向的; 也就是说,Facade对象发出子系统类的请求,反之则不然.相比之下,Mediator实现了同事对象不能或不能提供的协作行为,并且协议是多向的.
举一个简单的比喻:
门面:就像一个停车场,打电话时
parkingLot.Out(car1);
mab是一个简单的链工程:
{ car1.StartEngin(); attendant.charge(); car1.driverOut(); }
调解员:喜欢红绿灯.
光和汽车之间有相互作用,
汽车是由它的国家控制的.
我可能这可能是调解员"添加功能"
关于定义:
门面类型:结构
调解员的类型:行为
门面比较关心的成分都包含在 统一的界面,
和调解员关注一组对象 如何相互作用.