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

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

Разработчику Архитектору

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

Загрузка ArchiStyler…
Как пользоваться статьёй

Найдите в таблице ниже знакомую боль («много if по типам», «нужны подписки на события»), прочитайте один абзац про паттерн и перейдите по ссылке в узкую главу с кодом на Java или C#. Полный справочник по всем 23 паттернам GoF — в большом гиде и разделах порождающие, структурные, поведенческие.


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

ПаттернГруппаБоль в кодеИдея в одной фразе
FactoryПорождающийКлиент знает слишком много о конкретных классахСоздание объектов делегируют фабрике
SingletonПорождающийНужен ровно один координатор на процессОдин экземпляр и общая точка доступа
BuilderПорождающийКонструктор с десятком параметровСборка сложного объекта по шагам
AdapterСтруктурныйЧужой API не совпадает с вашим интерфейсомОбёртка переводит вызовы
CompositeСтруктурныйДерево «листья и папки» обрабатывают по-разномуЛист и узел — один интерфейс
DecoratorСтруктурныйПоведение наращивают без подклассовОбёртки с тем же интерфейсом
ProxyСтруктурныйДоступ к тяжёлому ресурсу нужно контролироватьЗаместитель с тем же контрактом
StrategyПоведенческийВетвления по способу оплаты, скидки, маршрутаАлгоритм выносится в заменяемый объект
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 паттерна GoF140, 111113
Архитектура системыархитектурные паттерны, design/intro
ООП в языкеJava, Python, C#

См. также

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").