Перейти к основному содержимому

Частые паттерны GoF в реальных проектах

Разработчику Архитектору
Теория данных (раздел 3)

На учебных схемах и в обзорах архитектуры обычно выделяют десять паттернов из каталога GoF, которые закрывают большинство повседневных задач: три порождающих, четыре структурных и три поведенческих. Их удобно учить после четырёх столпов ООП и SOLID: паттерн — это уже именованная схема из классов и интерфейсов, а не новый синтаксис языка.

Play ITЗагрузка интерактивного демо…

Как пользоваться статьёй

Найдите в таблице ниже знакомую боль ("много if по типам", "нужны подписки на события"), прочитайте один абзац про паттерн и перейдите по ссылке в узкую главу с кодом на Java или C#.

Полный справочник по всем 23 паттернам GoF — в большом гиде и разделах порождающие, структурные, поведенческие.


Сводная таблица

ПаттернГруппаБоль в кодеИдея в одной фразеМнемоника
FactoryПорождающийКлиент знает слишком много о конкретных классахСоздание объектов делегируют фабрикеПиццерии NY / Chicago
SingletonПорождающийНужен ровно один координатор на процессОдин экземпляр и общая точка доступаЕдинственный экземпляр на JVM
BuilderПорождающийКонструктор с десятком параметровСборка сложного объекта по шагам— (в приложении GoF)
AdapterСтруктурныйЧужой API не совпадает с вашим интерфейсомОбёртка переводит вызовыУтка + индюк
CompositeСтруктурныйДерево "листья и папки" обрабатывают по-разномуЛист и узел — один интерфейсМеню кафе
DecoratorСтруктурныйПоведение наращивают без подклассовОбёртки с тем же интерфейсомStarbuzz Coffee
ProxyСтруктурныйДоступ к тяжёлому ресурсу нужно контролироватьЗаместитель с тем же контрактомВиртуальный / удалённый объект
StrategyПоведенческийВетвления по способу оплаты, скидки, маршрутаАлгоритм выносится в заменяемый объектSimUDuck
ObserverПоведенческийМного подписчиков на одно событиеСубъект уведомляет наблюдателейМетеостанция
CommandПоведенческийДействия нужно ставить в очередь и отменятьЗапрос упакован в объектПульт ДУ

Порождающие паттерны

Factory (фабрика)

Задача. Клиенту нужны объекты общего интерфейса (Shape, Logger, Repository), но выбирать конкретный класс (Circle, FileLogger, PostgresRepository) в каждом месте вызова неудобно и ломает принцип открытости/закрытости.

Роли. ClientFactory → продукты (Circle, Square, …), реализующие Shape.

Где встречается. DI-контейнеры, DocumentBuilderFactory, фабрики HTTP-клиентов под окружение (dev / prod), создание UI-компонентов по типу виджета.

shape = factory.create("circle")
shape.draw()

Углубление. Порождающие паттерны · Factory Method в Java · Фабрика в C#

Singleton (одиночка)

Задача. В процессе должен существовать один экземпляр координатора — пул соединений, конфигурация приложения, диспетчер очереди.

Роли. Несколько Client обращаются к одному Instance через getInstance() или аналог.

Где встречается. Логгеры (осторожно с глобальным состоянием), кэш на уровне JVM/процесса; в enterprise-стеке ту же роль часто играет singleton-бин в Spring или .NET DI.

Риск. Скрытые зависимости и сложные тесты — предпочтительнее явная инъекция зависимостей, чем статический getInstance() в бизнес-коде.

Углубление. Singleton в Java · лаборатория Singleton на C#

Builder (строитель)

Задача. Объект с множеством необязательных полей (HttpRequest, SQL-запрос, UserProfile) нельзя честно собрать через конструктор с 15 параметрами.

Роли. Director или клиентский код → Builder по шагам (setEngine, setWheels) → готовый Product.

Где встречается. StringBuilder, fluent API (new Request.Builder().url(...).header(...).build()), конфигураторы тестовых данных.

Углубление. Builder в Java · порождающие


Структурные паттерны

Adapter (адаптер)

Задача. Есть полезный класс Adaptee с методом specificRequest(), а клиент ждёт Target.request().

Роли. Adapter implements Target и внутри вызывает Adaptee.

Где встречается. Обёртки над legacy SDK, преобразование форматов (XML → доменная модель), интеграция сторонних библиотек в свой слой портов.

Углубление. Adapter в Java · структурные

Composite (компоновщик)

Задача. Дерево элементов (меню, файловая система, сцена UI) нужно обходить единообразно: и файл, и папка поддерживают render() / getSize().

Роли. Component · Leaf · Composite (хранит children).

Где встречается. DOM-дерево, оргструктура, группы прав в ACL, деревья комментариев.

Углубление. Composite в Java

Decorator (декоратор)

Задача. Добавить обязанности (логирование, сжатие, кэш) динамически, не раздувая иерархию наследования CoffeeCoffeeWithMilkCoffeeWithMilkAndSugar.

Роли. Component · ConcreteComponent · Decorator (держит ссылку на Component) · ConcreteDecorator1, ConcreteDecorator2.

Где встречается. Потоки ввода-вывода (BufferedInputStream), middleware в HTTP, обёртки над репозиториями с кэшем.

Углубление. Decorator в Java

Proxy (заместитель)

Задача. Контролировать доступ к "тяжёлому" объекту — ленивая загрузка картинки, проверка прав, удалённый вызов.

Роли. ClientProxy и RealSubject, оба реализуют один интерфейс; прокси решает, когда создавать или вызывать реальный объект.

Где встречается. Lazy-loading ассетов, RPC-стабы, защищённые прокси к БД.

Углубление. Proxy в Java


Поведенческие паттерны

Strategy (стратегия)

Задача. Алгоритм (оплата, расчёт скидки, маршрут доставки) меняется независимо от контекста (ShoppingCart, Navigator).

Роли. Context хранит PaymentStrategy; реализации CreditCardPayment, PayPalPayment взаимозаменяемы.

Где встречается. Политики ценообразования, выбор сериализатора JSON/XML, стратегии retry в клиентах API.

cart.setPayment(new PayPalPayment())
cart.checkout()

Углубление. Strategy в Java · Стратегия в C#

Observer (наблюдатель)

Задача. При изменении состояния (Subject) нужно уведомить множество заинтересованных объектов без жёсткой связи списком имён классов.

Роли. Subject хранит список Observer; при событии вызывает update() у каждого подписчика.

Где встречается. UI-события, pub/sub в брокерах сообщений, реактивные стримы (addEventListener в браузере, subscribe в Rx), доменные события в DDD.

Связь с ООП. Прямое применение полиморфизма: разные наблюдатели реагируют на одно уведомление по-своему.

Углубление. Observer в Java · Наблюдатель в C#

Command (команда)

Задача. Действие пользователя (кнопка пульта, пункт меню, API "отменить") нужно оформить как объект, который можно ставить в очередь, логировать и откатывать.

Роли. Invoker (RemoteControl) → CommandReceiver (Device).

Где встречается. Undo/redo в редакторах, очереди задач, CQRS-команды, macro-записи.

Углубление. Command в Java · Команда в C#


Связь с разделами энциклопедии

УровеньМатериал
ООП без языка4-08-oop
Принципы проектированияSOLID
Все 23 паттерна GoFGoF паттерны в Java - большой практический гид, Порождающие паттерныПоведенческие паттерны
Архитектура системыархитектурные паттерны, design/intro
Сеть, API, очереди (когда паттерн выходит за процесс)2.09 · Паттерны интеграции внешних систем — интеграция
ООП в языкеJava, Python, C#

См. также