外墙与调解员

问题描述 投票:74回答:8

我一直在研究这两种模式之间的区别。

据我所知,facade封装了对子系统的访问,而mediator封装了组件之间的交互。

我知道子系统组件不知道外观,因为组件明显知道中介。

我目前正在使用外观来封装检索配置信息的方法,例如, App.Config,存储在SQL中的用户设置,程序集信息等,以及用于在不同窗体之间导航的介体。

但是,大多数网站都指出调解员“增加了功能”。这是什么意思?介体如何添加功能?

design-patterns facade mediator
8个回答
93
投票

...大多数网站指出调解员“增加功能”......

外观仅从不同的角度公开现有功能。

介体“添加”功能,因为它结合了不同的现有功能来创建新功能。

请看以下示例:

你有一个日志系统。从该日志记录系统,您可以登录到文件,套接字或数据库。

使用外观设计模式,您将“隐藏”现有功能的所有关系,这些关系位于外观所暴露的单个“界面”背后。

客户代码:

 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();
               }
      }
 }

在此代码中,介体是包含业务逻辑的介体,用于创建记录的相应“通道”以及将日志导入该通道。调解员正在“创建”功能。

当然,有更好的方法可以使用多态实现这一点,但这里的重点是展示调解器如何通过组合现有功能来“添加”新功能(在我的示例中没有显示非常抱歉),但想象一下调解器,阅读从数据库远程主机到哪里记录,然后创建一个客户端,最后写入该客户端打印流的日志消息。这样,调解者将在不同对象之间“调解”。

最后,外观是一种结构模式,即它描述了对象的组成,而中介是一种行为,即它描述了对象的交互方式。

我希望这有帮助。


12
投票

我正在使用mediator添加日志文件功能。

它的工作原理如下:

  • Obj A告诉调解员需要完成的事情。
  • 中介将消息发送到各种客户端对象。
  • Obj B执行Obj A需要的事情,并通过调解器发回适当的消息。
  • 同时,Obj C也由调解员发送两条消息,并记录结果。这样,我们就可以从日志文件中获取用户统计信息。
  • Obj D也可以是错误检查器,因此如果Obj B响应Obj A的请求是不可能的,Obj D可能是向用户报告的事情。错误现在可以记录在与常规活动不同的文件中,并且可以使用一些其他方法来表示Obj A不应该真正关注的行为(嘟嘟声等等)。

10
投票

在相关模式下,gof说:Facade(185)与Mediator的不同之处在于它抽象了一个对象子系统以提供更方便的界面。它的协议是单向的;也就是说,Facade对象发出子系统类的请求,反之则不然。相比之下,Mediator实现了同事对象不能或不能提供的协作行为,并且协议是多向的。


6
投票

举一个简单的比喻:

门面:就像一个停车场,打电话时

parkingLot.Out(car1);

mab是一个简单的链工程:

{
  car1.StartEngin();      
  attendant.charge();
  car1.driverOut();
}

调解员:喜欢红绿灯。

光和汽车之间有相互作用,

汽车是由它的国家控制的。

我可能这可能是调解员“添加功能”


关于定义:

门面类型:结构

调解员的类型:行为

门面更关注组件包含在统一界面中,

和调解员关注一组对象如何相互作用。


4
投票

我认为区别是方向性的:门面是客户和门面之间的单向沟通;中介可以是双向对话,消息在客户端和中介之间来回流动。


3
投票

从“设计模式”一书中,中介模式的关键描述如下:“它(一个中介)充当小部件的通信中心(即'一组相互依赖的对象)。”

换句话说,中介对象是唯一的超级对象,它知道一组协作对象中的所有其他对象以及它们应如何相互交互。所有其他对象应该与介体对象交互,而不是彼此交互。

相比之下,外观是子系统中一组接口的“统一接口” - 供子系统的消费者使用 - 而不是子系统的组件之间。


1
投票

您可以在此SE问题中找到有关Facade模式的详细信息:

What is Facade Design Pattern?

Facade为复杂系统提供了一个简单而统一的界面。

这篇文章提供了真实世界的例子(cleartrip航班+酒店预订):

What is Facade Design Pattern?

Mediator模式:定义一个封装一组对象如何交互的对象。 Mediator通过使对象明确地相互引用来促进松散耦合,并且它允许您独立地改变它们的交互。

以下SE问题中提供了一个真实的Mesh网络拓扑示例:

Mediator Vs Observer Object-Oriented Design Patterns

关于您对Mediator的查询增加了责任:

  1. Facade仅提供现有子系统的接口。现有的子系统不了解Facade类本身。
  2. 调解员知道同事的对象。它实现了不同同事之间的沟通。在我在链接问题中引用的示例中,ConcreteMediator(NetworkMediator)向所有其他同事发送注册和取消注册一位同事事件的通知。

1
投票

两者都对另一组对象施加某种策略。 Facade从上面强制执行政策,Mediator从下面强加政策。 Facade的使用是可见的和约束的,而Mediator的使用是不可见的和启用的。

当您想要为具有复杂和通用接口的一组对象提供简单且特定的接口时,将使用Facade模式。

Mediator模式也强加了政策。然而,虽然Facade以明显和有限的方式强加其政策,但Mediator以隐藏和不受约束的方式强加其政策。

敏捷软件开发,原则,模式和实践Robert C. Martin。

© www.soinside.com 2019 - 2024. All rights reserved.