我一直在研究这两种模式之间的区别。
我知道外观封装了对子系统的访问,而中介封装了组件之间的交互。
我知道子系统组件不知道外观,而组件显然知道中介。
我目前正在使用外观来封装检索配置信息的方法,例如 App.Config、存储在 SQL 中的用户设置、程序集信息等,以及用于在不同窗体之间导航的中介。
然而,大多数网站都指出中介“增加了功能”。他们这是什么意思?中介如何添加功能?
我一直在研究这两种模式之间的区别。
我知道外观封装了对子系统的访问,而中介封装了组件之间的交互。
我知道子系统组件不知道外观,而组件显然知道中介。
我目前正在使用外观来封装检索配置信息的方法,例如 App.Config、存储在 SQL 中的用户设置、程序集信息等,以及用于在不同窗体之间导航的中介。
然而,大多数网站都指出中介“增加了功能”。他们这是什么意思?中介如何添加功能?
...大多数网站指出中介“增加了功能”...
外观仅从不同的角度公开现有功能。
中介“添加”功能,因为它结合了不同的现有功能来创建新功能。
举个例子:
你有一个日志系统。从该日志系统,您可以将日志记录到文件、套接字或数据库。
使用外观设计模式,您可以将现有功能的所有关系“隐藏”在外观暴露的单个“界面”后面。
客户端代码:
Logger logger = new Logger();
logger.initLogger("someLogger");
logger.debug("message");
该实现可能涉及许多对象的交互。但最终,该功能已经存在。大概“调试”方法实现如下:
执行:
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 是具有“调试”方法的包私有对象。这样,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();
}
}
}
在此代码中,中介是包含创建适当“通道”以记录日志并将日志放入该通道的业务逻辑的那个。中介正在“创建”功能。
当然,使用多态性有更好的方法来实现这一点,但这里的重点是展示中介如何通过组合现有功能“添加”新功能(在我的示例中没有表现出非常抱歉)但想象一下中介,阅读从数据库中记录远程主机的位置,然后创建一个客户端,最后将日志消息写入该客户端打印流。这样,调解员将在不同对象之间“调解”。
最后,外观是一种结构模式,即描述对象的组成,而中介是一种行为模式,即描述对象交互的方式。
我希望这有帮助。
我正在使用调解器来添加日志文件功能。
它是这样工作的:
在相关模式下,gof说: Facade (185) 与 Mediator 的不同之处在于它抽象了对象子系统以提供更方便的接口。它的协议是单向的;也就是说,Facade 对象向子系统类发出请求,反之则不然。相比之下,Mediator 实现了同事对象不提供或不能提供的协作行为,并且协议是多向的。
我认为区别是有方向的:Facade 是客户端和 Facade 之间的一种单向通信;mediator 可以是双向对话,消息在客户端和 mediator 之间来回流动。
在“设计模式”一书中,中介者模式的关键描述如下:“它(中介者)充当小部件(即,'一组'相互依赖的对象)的通信中心。”
换句话说,中介对象是唯一的超对象,它知道一组协作对象中的所有其他对象以及它们应该如何相互交互。所有其他对象都应该与中介对象交互,而不是彼此交互。
相反,外观是子系统中一组接口的“统一接口”——供子系统的消费者使用——而不是子系统的组件。
您可以在这个 SE 问题中找到有关外观模式的详细信息:
Facade
为复杂系统提供简单统一的接口。
这篇文章中提供了真实世界的示例(cleartrip 航班+酒店预订):
中介者模式:定义一个对象,封装一组对象如何交互。Mediator 通过阻止对象显式地相互引用来促进松散耦合,并且它允许您独立地改变它们的交互。
下面的 SE 问题中提供了 Mesh 网络拓扑的真实示例:
关于您对 Mediator 的查询增加了责任:
Facade 仅提供与现有子系统的接口。现有的子系统不知道 Facade 类本身。
中介者知道同事对象。它使不同同事之间的沟通成为可能。在我在链接问题中引用的示例中,ConcreteMediator ( NetworkMediator ) 将一位同事的注册和注销事件的通知发送给所有其他同事。
两者都对另一组对象施加某种策略。Facade从上执行策略,Mediator从下执行策略。Facade的使用是可见的和约束的,而Mediator的使用是不可见的和启用的。
当您想为一组具有复杂和通用接口的对象提供简单和特定的接口时,使用外观模式。
The Mediator pattern also imposes policy. However, whereas Facade imposed its policy in a visible and constraining way, Mediator imposes its policies in a hidden and unconstrained way.
Agile Software Development, Principles, Patterns, and Practices Robert C. Martin.