Фасад — это структурный паттерн, который предоставляет простой (но урезанный) интерфейс к сложной системе объектов, библиотеке или фреймворку.
Кроме того, что Фасад позволяет снизить общую сложность программы, он также помогает вынести код, зависимый от внешней системы в единственное место.
Сложность:
Популярность:
Применимость: Паттерн часто встречается в клиентских приложениях, написанных на Ruby, которые используют классы-фасады для упрощения работы со сложными библиотеки или API.
Признаки применения паттерна: Фасад угадывается в классе, который имеет простой интерфейс, но делегирует основную часть работы другим классам. Чаще всего, фасады сами следят за жизненным циклом объектов сложной системы.
Концептуальный пример
Этот пример показывает структуру паттерна Фасад , а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
main.rb: Пример структуры паттерна
# Класс Фасада предоставляет простой интерфейс для сложной логики одной или
# нескольких подсистем. Фасад делегирует запросы клиентов соответствующим
# объектам внутри подсистемы. Фасад также отвечает за управление их жизненным
# циклом. Все это защищает клиента от нежелательной сложности подсистемы.
class Facade
# В зависимости от потребностей вашего приложения вы можете предоставить
# Фасаду существующие объекты подсистемы или заставить Фасад создать их
# самостоятельно.
#
# @param [Subsystem1] subsystem1
# @param [Subsystem2] subsystem2
def initialize(subsystem1, subsystem2)
@subsystem1 = subsystem1 || Subsystem1.new
@subsystem2 = subsystem2 || Subsystem2.new
end
# Методы Фасада удобны для быстрого доступа к сложной функциональности
# подсистем. Однако клиенты получают только часть возможностей подсистемы.
#
# @return [String]
def operation
results = []
results.append('Facade initializes subsystems:')
results.append(@subsystem1.operation1)
results.append(@subsystem2.operation1)
results.append('Facade orders subsystems to perform the action:')
results.append(@subsystem1.operation_n)
results.append(@subsystem2.operation_z)
results.join("\n")
end
end
# Подсистема может принимать запросы либо от фасада, либо от клиента напрямую. В
# любом случае, для Подсистемы Фасад – это ещё один клиент, и он не является
# частью Подсистемы.
class Subsystem1
# @return [String]
def operation1
'Subsystem1: Ready!'
end
# ...
# @return [String]
def operation_n
'Subsystem1: Go!'
end
end
# Некоторые фасады могут работать с разными подсистемами одновременно.
class Subsystem2
# @return [String]
def operation1
'Subsystem2: Get ready!'
end
# ...
# @return [String]
def operation_z
'Subsystem2: Fire!'
end
end
# Клиентский код работает со сложными подсистемами через простой интерфейс,
# предоставляемый Фасадом. Когда фасад управляет жизненным циклом подсистемы,
# клиент может даже не знать о существовании подсистемы. Такой подход позволяет
# держать сложность под контролем.
#
# @param [Facade] facade
def client_code(facade)
print facade.operation
end
# В клиентском коде могут быть уже созданы некоторые объекты подсистемы. В этом
# случае может оказаться целесообразным инициализировать Фасад с этими объектами
# вместо того, чтобы позволить Фасаду создавать новые экземпляры.
subsystem1 = Subsystem1.new
subsystem2 = Subsystem2.new
facade = Facade.new(subsystem1, subsystem2)
client_code(facade)
output.txt: Результат выполнения
Facade initializes subsystems:
Subsystem1: Ready!
Subsystem2: Get ready!
Facade orders subsystems to perform the action:
Subsystem1: Go!
Subsystem2: Fire!
Фасад на других языках программирования