我一直在研究这两种模式之间的区别。
据我所知,facade封装了对子系统的访问,介体封装了组件之间的交互。
我知道子系统组件不知道外观,因为组件明显知道中介。
我目前正在使用外观来封装检索配置信息的方法,例如: App.Config,存储在SQL中的用户设置,程序集信息等,以及用于在不同窗体之间导航的介体。
但是,大多数网站都指出调解员“增加了功能”。这是什么意思?介体如何添加功能?
答案 0 :(得分:91)
...大多数网站都指出调解员“添加功能”......
facade 仅从不同的角度公开现有功能。
介体“添加”功能,因为它结合了不同的现有功能来创建新功能。
采用以下示例:
您有一个日志记录系统。从该日志记录系统,您可以登录到文件,套接字或数据库。
使用外观设计模式,您将“隐藏”现有功能的所有关系,这些关系来自外观所暴露的单个“界面”。
客户端代码:
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();
}
}
}
在此代码中,介体是包含业务逻辑的介体,用于创建记录的相应“通道”以及使日志进入该通道。调解员正在“创建”功能。
当然,有更好的方法可以使用多态实现这一点,但这里的重点是展示调解器如何通过组合现有功能来“添加”新功能(在我的示例中没有显示非常抱歉)但想象一下介体,从数据库中读取远程主机在哪里记录,然后创建一个客户端,最后写入该客户端打印流的日志消息。这样,调解员就会在不同的物体之间“调解”。
最后, facade 是一种结构模式,即它描述了对象的组成,而中介是一种行为,也就是说,它描述了方式对象互动。
我希望这会有所帮助。
答案 1 :(得分:12)
我正在使用mediator添加日志文件功能。
它的工作原理如下:
答案 2 :(得分:10)
在相关模式下,gof说:Facade(185)与Mediator的不同之处在于它抽象对象的子系统以提供更方便的界面。它的协议是单向的;也就是说,Facade对象发出子系统类的请求,反之则不然。相比之下,Mediator实现了同事对象不能或不能提供的协作行为,并且协议是多向的。
答案 3 :(得分:6)
举一个简单的比喻:
门面:像停车场一样,打电话时
parkingLot.Out(car1);
mab是一个简单的链条工作:
{
car1.StartEngin();
attendant.charge();
car1.driverOut();
}
调解员:喜欢红绿灯。
光与汽车之间存在相互作用,
并且汽车由其状态控制。
我可能这可能是调解员“添加功能”
关于定义:
Facade的类型:结构
调解员类型:行为
统一界面 >>和调解员关注如何一组对象互动。
答案 4 :(得分:4)
我认为区别是方向性的:门面是客户与门面之间的单向沟通;中介可以是双向对话,消息在客户端和中介之间来回传递。
答案 5 :(得分:3)
从“设计模式”一书中,介体模式的KEY描述如下: “它(调解员)充当小部件通信的枢纽(即”一组相互依赖的对象“)。”
换句话说,中介对象是唯一的超级对象,它知道一组协作对象中的所有其他对象以及它们应如何相互交互。所有其他对象应该与介体对象交互,而不是彼此交互。
相比之下,Facade是子系统中一组接口的“统一接口” - 供子系统的消费者使用 - 而不是子系统的组件。
答案 6 :(得分:1)
您可以在此SE问题中找到有关Facade模式的详细信息:
What is Facade Design Pattern?
Facade
为复杂系统提供了一个简单而统一的界面。
这篇文章提供了真实世界的例子( cleartrip航班+酒店预订):
What is Facade Design Pattern?
Mediator pattern:定义一个封装一组对象如何交互的对象。 Mediator通过使对象明确地相互引用来促进松散耦合,并且它允许您独立地改变它们的交互。
以下SE问题提供了一个真实世界的网状网络拓扑示例:
Mediator Vs Observer Object-Oriented Design Patterns
关于您对Mediator的查询增加了责任:
Facade仅提供现有子系统的界面。现有的子系统不了解Facade类本身。
Mediator了解同事对象。它实现了不同同事之间的沟通。在我在链接问题中引用的示例中, ConcreteMediator ( NetworkMediator )向所有其他同事发送注册和取消注册一位同事事件的通知。
答案 7 :(得分:1)
两者都对另一组对象施加某种策略。 Facade 从上面强加政策, Mediator 从下面强加政策。使用 Facade 是可见和约束的,而 Mediator 的使用是不可见的并且可以启用。
如果要为具有复杂通用界面的一组对象提供简单且特定的界面,则使用 Facade 模式。
Mediator 模式也强加了政策。然而,虽然Facade以明显和有限的方式强加其政策,但 Mediator 以隐蔽和不受约束的方式强加其政策。
敏捷软件开发,原则,模式和实践Robert C. Martin。