Классы подсистемы ничего не «знают» о существовании фасада, то есть не хранят ссылок на него.
Фасад может также упростить процесс переноса системы на другие платформы, поскольку уменьшается вероятность того, что в результате изменения одной подсистемы понадобится изменять и все остальные.
Шаблон “фасад” структурный шаблон проектирования, позволяющий скрыть сложность системы путем сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.
Проблема: как обеспечить унифицированный интерфейс с набором разрозненных реализаций или интерфейсов, например, с подсистемой, если нежелательно высокое связывание с этой подсистемой или реализация подсистемы может измениться?
Решение: определить одну точку взаимодействия с подсистемой — фасадный объект, обеспечивающий общий интерфейс с подсистемой, и возложить на него обязанность по взаимодействию с её компонентами.
Фасад — это внешний объект, обеспечивающий единственную точку входа для служб подсистемы. Реализация других компонентов подсистемы закрыта и не видна внешним компонентам.
На C#
using System;
Namespace Library
{
class SubsystemA
{
public string OperationA1()
{
return "Subsystem A, Method A1\n";
}
public string OperationA2()
{
return "Subsystem A, Method A2\n";
}
}
class SubsystemB
{
public string OperationB1()
{
return "Subsystem B, Method B1\n";
}
public string OperationB2()
{
return "Subsystem B, Method B2\n";
}
}
class SubsystemC
{
public string OperationC1()
{
return "Subsystem C, Method C1\n";
}
public string OperationC2()
{
return "Subsystem C, Method C2\n";
}
}
public class Facade
{
private SubsystemA a = new SubsystemA();
private SubsystemB b = new SubsystemB();
private SubsystemC c = new SubsystemC();
public void Operation1()
{
Console.WriteLine("Operation 1\n" +
a.OperationA1() +
a.OperationA2() +
b.OperationB1());
}
public void Operation2()
{
Console.WriteLine("Operation 2\n" +
b.OperationB2() +
c.OperationC1() +
c.OperationC2());
}
}
}
Class Program
{
static void Main(string[] args)
{
Facade.Operation1();
Facade.Operation2();
// Wait for user
Console.Read();
}
}
//пример
Namespace Sample
{
// The 'Subsystem ClassA' class
class CarModel
{
public void SetModel()
{
Console.WriteLine(" CarModel - SetModel");
}
}
/// <summary>
/// The 'Subsystem ClassB' class
/// </summary>
class CarEngine
{
public void SetEngine()
{
Console.WriteLine(" CarEngine - SetEngine");
}
}
// The 'Subsystem ClassC' class
class CarBody
{
public void SetBody()
{
Console.WriteLine(" CarBody - SetBody");
}
}
// The 'Subsystem ClassD' class
class CarAccessories
{
public void SetAccessories()
{
Console.WriteLine(" CarAccessories - SetAccessories");
}
}
// The 'Facade' class
public class CarFacade
{
private CarModel model;
private CarEngine engine;
private CarBody body;
private CarAccessories accessories;
public CarFacade()
{
model = new CarModel();
engine = new CarEngine();
body = new CarBody();
accessories = new CarAccessories();
}
public void CreateCompleteCar()
{
Console.WriteLine("******** Creating a Car **********\n");
model.SetModel();
engine.SetEngine();
body.SetBody();
accessories.SetAccessories();
Console.WriteLine("\n***** Car creation is completed*****");
}
}
// Facade Pattern Demo
class Program
{
static void Main(string[] args)
{
CarFacade facade = new CarFacade();
facade.CreateCompleteCar();
Console.Read();
}
}
}
У паттерна фасад есть следующие преимущества:
1. Изолирует клиентов от компонентов подсистемы
Уменьшая тем самым число объектов, с которыми клиентам приходится иметь дело, упрощая работу с подсистемой.
2. Позволяет ослабить связанность между подсистемой и ее клиентами.
Зачастую компоненты подсистемы сильно связаны: многие классы из разных частей и слоев системы взаимодействуют с друг другом, меняя один такой класс, приходится перекомпилировать и остальные связанные и т.д. Слабая связанность позволяет видоизменять компоненты, не затрагивая при этом клиентов. Фасады помогают разложить систему на слои и структурировать зависимости между объектами, а также избежать сложных и циклических зависимостей. Это оказывается важным, если клиент и подсистема реализуются независимо.
Уменьшение числа зависимостей на стадии компиляции чрезвычайно важно в больших системах. Хочется, конечно, чтобы время, уходящее на перекомпиляцию после изменения классов подсистемы, было минимальным. Сокращение числа зависимостей за счет фасадов может уменьшить количество нуждающихся в повторной компиляции файлов после небольшой модификации какой-нибудь важной подсистемы. Фасад может также упростить процесс переноса системы на другие платформы, поскольку уменьшается вероятность того, что в результате изменения одной подсистемы понадобится изменять и все остальные.
3. Фасад не исключает возможности приложениям напрямую обращаться к классам подсистемы, если это необходимо. Таким образом, у вас есть выбор между простотой и общностью. Совет конечно очевидный: как можно только в крайних случаях прибегайте к прямому взаимодействию с классом за фасадом, лучше если возможно все же как-нибудь обобщить/абстрагировать эту операцию и добавить ее в сам фасад.
Заместитель (Proxy)