Снижение сложности интерфейса (Reducing interface complexity)


Иногда проблема, решаемая вами, определяется фразой: "У меня нет интерфейса, который я хочу". Façade создает интерфейс для множества классов, просто обеспечивая более комфортный способ работы с библиотекой или каким-то ресурсом.

Facade

Общий принцип, применяемый мной при попытке формировать требования к объекту первого приближения, следующий: "Если что-то уродливо, нужно спрятать это внутри объекта". Это основная работа, выполняемая Facade. Если у вас есть сбивающий с толку набор классов и интерфейсов, которые реально не нужно видеть клиентскому программисту, то вы можете создать интерфейс, который полезен клиентскому программисту и представляет только то, что вам действительно необходимо.

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

//: facade:Facade.java
package facade;

import junit.framework.*;

class A {
  
public A(int x) {
   }
}

class B {
  
public B(long x) {
   }
}

class C {
  
public C(double x) {
   }
}

// Другие классы, которые не выставляются
// фасадом, идут здесь ...
public class Facade extends TestCase {
  
static A makeA(int x) {
     
return new A(x);
  
}
  
  
static B makeB(long x) {
     
return new B(x);
  
}
  
  
static C makeC(double x) {
     
return new C(x);
  
}
  
  
public void test() {
     
// Клиентский программист получает объекты,
      // вызывая статические методы:
     
A a = Facade.makeA(1);
      B b = Facade.makeB
(1);
      C c = Facade.makeC
(1.0);
  
}
  
  
public static void main(String args[]) {
     
junit.textui.TestRunner.run(Facade.class);
  
}
}
// /:~

Пример, приведенный в книге Design Patterns, является просто классом, использующим другие классы.

Советчик по налогам является Фасадом между вами и налоговым законодательством и посредником между вами и налоговой системой.

Пакет, как вариация Facade

Для меня Facade скорее "процедурный" (не объектно-ориентированный) подход: вы просто вызываете некоторые функции, чтобы получить объекты. А чем это отличается, на самом деле, от Абстрактной Фабрики? Назначение Facade состоит в том, чтобы спрятать часть библиотеки классов (и их взаимодействий) от клиентского программиста, чтобы сделать интерфейс этой группы классов более удобоваримым и легким в понимании.

Однако, это именно то свойство, которое достигается пакетированием в Java: вне библиотеки вы можете только создавать и использовать публичные классы. Все не-публичные классы доступны только внутри пакета. Таким образом, Facade является встроенной возможностью Java.

Для чистоты скажем, что Design Patterns написан в основном для C++ аудитории. Хотя C++ имеет пространство имен для предотвращения совпадения переменных и имен классов, это не предоставляет механизм прятанья классов, который мы имеем с не-публичными классами в Java. Так что в настоящем я думаю, что Java пакеты решили проблему фасадов.