Структура работы Abstract Factory
- Абстрактные продукты объявляют интерфейсы продуктов, которые связаны друг с другом по смыслу, но выполняют разные функции.
- Конкретные продукты — это большой набор классов, которые относятся к различным абстрактным продуктам (кресло/столик), но имеют одни и те же вариации (викторианский/модерн).
- Абстрактная фабрика объявляет методы создания различных абстрактных продуктов (кресло/столик).
- Конкретные фабрики относятся каждая к своей вариации продуктов (викторианский/модерн) и реализуют методы абстрактной фабрики, позволяя создавать все продукты определённой вариации.
- Несмотря на то что конкретные фабрики порождают конкретные продукты, сигнатуры их методов должны возвращать соответствующие абстрактные продукты. Это позволит клиентскому коду, использующему фабрику, не привязываться к конкретным классам продуктов. Клиент сможет работать с любыми вариациями продуктов через абстрактные интерфейсы.
Псевдокод
В этом примере абстрактная фабрика создаёт кросс-платформенные элементы интерфейса и следит за тем, чтобы они соответствовали выбранной операционной системе.
Пример кросс-платформенного графического интерфейса пользователя
Кросс-платформенная программа может показывать одни и те же элементы интерфейса, выглядящие чуть-чуть иначе в различных операционных системах. В такой программе важно, чтобы все создаваемые элементы всегда соответствовали текущей операционной системе. Тебе бы не хотелось, чтобы программа, запущенная на Windows, вдруг начала показывать чекбоксы в стиле macOS.
Абстрактная фабрика объявляет список создающих методов, которые клиентский код может использовать для получения тех или иных разновидностей элементов интерфейса. Конкретные фабрики относятся к различным операционным системам и создают элементы, совместимые с этой системой.
В самом начале программа определяет, какая из фабрик соответствует текущей операционке. Затем создаёт эту фабрику и отдаёт её клиентскому коду. В дальнейшем клиент будет работать только с этой фабрикой, чтобы исключить несовместимость возвращаемых продуктов.
Клиентский код не зависит от конкретных классов фабрик и элементов интерфейса. Он общается с ними через абстрактные интерфейсы. Благодаря этому клиент может работать с любой разновидностью фабрик и элементов интерфейса.
Чтобы добавить в программу новую вариацию элементов (например, для поддержки Linux), тебе не нужно трогать клиентский код. Достаточно создать ещё одну фабрику, производящую эти элементы.