Фасад против посредника


83

Я исследовал разницу между этими двумя паттернами.

Я понимаю, что фасад инкапсулирует доступ к подсистеме, а посредник инкапсулирует взаимодействия между компонентами.

Я понимаю, что компоненты подсистемы не знают о фасаде, тогда как компоненты, очевидно, знают о посреднике.

В настоящее время я использую фасад для инкапсуляции метода получения информации о конфигурации, например App.Config, пользовательских настроек, хранящихся в SQL, информации о сборке и т. Д., А также посредника для навигации между различными формами окон.

Однако большинство сайтов отмечают, что посредник «добавляет функциональность». Что они имеют в виду? Как посредник добавляет функциональность?

Ответы:


103

... большинство сайтов отмечают, что посредник «добавляет функциональность» ...

Фасад только обнажает существующие функциональные возможности с другой точки зрения.

Посредник «добавляет» функциональность , поскольку он сочетает в себе различные существующие функциональные возможности для создания нового.

Возьмем следующий пример:

У вас есть система регистрации. Из этой системы ведения журнала вы можете войти в файл, в сокет или в базу данных.

Используя шаблон проектирования фасада, вы «спрячете» все взаимосвязи существующей функциональности за единым «интерфейсом», который предоставляет фасад.

Код клиента:

 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 является закрытым для пакета объектом, имеющим метод «отладки». Таким образом, фасад не добавляет функциональности, а просто делегирует некоторые существующие объекты.

С другой стороны, посредник добавляет новую функциональность, комбинируя разные объекты.

Тот же клиентский код:

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

В этом коде посредником является тот, который содержит бизнес-логику для создания соответствующего «канала» для входа в систему, а также для выполнения входа в этот канал. Посредник «создает» функциональность.

Конечно, есть более эффективные способы реализовать это с помощью полиморфизма, но суть здесь в том, чтобы показать, как посредник «добавляет» новые функции, комбинируя существующие функции (в моем примере не очень-то жаль), но представьте себе посредника, прочтите из базы данных - удаленный хост, на котором нужно вести журнал, затем создает клиента и, наконец, записывает в поток печати этого клиента сообщение журнала. Таким образом, посредник будет «посредником» между различными объектами.

Наконец, фасад - это структурный паттерн, то есть он описывает состав объектов, в то время как посредник является поведенческим, то есть описывает способ взаимодействия объектов.

Надеюсь, это поможет.


Отличное объяснение .. У меня есть вопрос по этому поводу. Способ составления ReentrantLock и AbstractQueueSynchronizer (AQS) вписывается в пример паттерна фасада? Я имею в виду, что ReentrantLock раскрывает только функциональность AQS, которая присутствует внутри него как подсистема.
AKS

Ответ @RayTayek противоречит вашему ответу? Протокол вашего посредника однонаправлен, верно?
Нарек

Я не смог найти ни одного сайта (включая википедию), на котором говорилось бы, что посредник добавляет новые функции. Вы можете указать какие-нибудь ссылки?
Разработчик

@developer вот ссылка , посмотрите внизу.
Дарио Фумагалли

13

Я использую посредник, чтобы добавить функциональность файла журнала.

Это работает так:

  • Obj A сообщает посреднику, что нужно что-то сделать.
  • Посредник отправляет сообщение различным клиентским объектам.
  • Obj B делает то, что нужно Obj A, и отправляет соответствующее сообщение обратно через посредника.
  • Между тем, Obj C также отправляет оба сообщения посредником и регистрирует результаты. Таким образом, мы можем получать статистику пользователей из файлов журнала.
  • Obj D также может быть средством проверки ошибок, так что если Obj B отвечает, что запрос Obj A невозможен, Obj D может быть тем, что сообщает об этом пользователю. Ошибки теперь могут регистрироваться в файле, отличном от обычного, и могут использовать другие средства для поведения (звуковые сигналы, что угодно), которые Obj A не должны беспокоить.

12

В соответствии со связанными шаблонами gof говорит: Facade (185) отличается от Mediator тем, что он абстрагирует подсистему объектов, чтобы обеспечить более удобный интерфейс. Его протокол однонаправлен; то есть объекты фасада запрашивают классы подсистем, но не наоборот. Напротив, посредник обеспечивает совместное поведение, которое объекты-коллеги не могут или не могут обеспечить, а протокол является разнонаправленным.


8

Возьмите простую аналогию:

Фасад: как парковка, при звонке

parkingLot.Out(car1);

mab будет простая цепочка работает:

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

Посредник: как светофор.

Есть взаимодействие между светом и автомобилем,

и автомобили контролируются его государством.

Я подумал, может быть, это посредник «добавляет функциональности»


А по поводу определения:

Тип фасада: Структурный

Тип посредника: поведенческий

фасад более обеспокоено о компонентах были содержатся в едином интерфейсе ,

и посредник касаются того, как взаимодействует набор объектов .


4

Я думал, что различие было направленным: фасад - это односторонняя связь между клиентом и фасадом; посредником может быть двусторонний диалог, при котором сообщения перемещаются между клиентом и посредником.


Извините, но эта разница на самом деле неверна, ответ ммр правильный. Хотя я тоже верил в то же, что и вы, когда впервые посмотрел на них
Роберт Гулд

3

В книге «Паттерны проектирования» КЛЮЧ паттерна «Посредник» описывается следующим образом: «Он (посредник) действует как ХАБ связи для виджетов (то есть« группа »взаимозависимых объектов)».

Другими словами, объект-посредник - это единственный суперобъект, который знает все другие объекты в группе взаимодействующих объектов и то, как они должны взаимодействовать друг с другом. Все остальные объекты должны взаимодействовать с объектом-посредником, а не друг с другом.

Напротив, фасад - это «унифицированный интерфейс» для набора интерфейсов в подсистеме - для использования потребителями подсистемы - а не среди компонентов подсистемы.


1

Вы можете найти подробную информацию о фасаде в этом вопросе SE:

Что такое шаблон оформления фасада?

Facade обеспечивает простой и унифицированный интерфейс для сложной системы.

Пример из реального мира ( рейс cleartrip + бронирование отелей ) доступен в этом посте:

Что такое шаблон оформления фасада?

Шаблон посредника : определите объект, который инкапсулирует, как взаимодействует набор объектов. Посредник способствует слабой связи, не позволяя объектам явно ссылаться друг на друга, и позволяет вам изменять их взаимодействие независимо.

Реальный пример топологии Mesh-сети представлен в следующем вопросе SE:

Объектно-ориентированные шаблоны проектирования Mediator против Observer

Касательно вашего запроса о Посреднике добавляет ответственности:

  1. Фасад предоставляет только интерфейс к существующим подсистемам . Существующие подсистемы не знают о самом классе Facade.

  2. Посредник знает о объектах-коллегах . Это позволяет общаться между разными коллегами. В примере, который я привел в связанном вопросе, ConcreteMediator ( NetworkMediator ) отправляет уведомления о регистрации и отмене регистрации одного коллеги всем другим коллегам.


1

Оба налагают какую-то политику на другую группу объектов. Фасад навязывает политику сверху, а Посредник навязывает политику снизу. Использование Facade является видимым и ограничивающим, в то время как использование Mediator невидимо и дает возможность.

Фасад шаблон используется , когда вы хотите , чтобы обеспечить простой и конкретный интерфейс к группе объектов, имеет сложный и общий интерфейс.

Посредник модель также налагает политику. Однако, в то время как Facade навязывает свою политику видимым и ограничивающим образом, Mediator навязывает свою политику скрытым и неограниченным образом.

Гибкая разработка программного обеспечения, принципы, шаблоны и практики Роберт К. Мартин.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.