Порождающие паттерны (Creational Patterns)¶
Какую проблему решает эта категория¶
Порождающие паттерны отвечают на один вопрос: как создавать объекты так, чтобы код, который их создаёт, не был жёстко привязан к конкретным классам этих объектов.
Самый простой способ создать объект в C# - оператор new SomeClass(). Но у прямого new есть скрытая цена:
- код, вызвавший
new, теперь знает и зависит от конкретного типаSomeClass, а не от абстракции; - если логика создания объекта усложняется (нужно выбрать один из нескольких классов, собрать объект из многих частей, переиспользовать уже созданный экземпляр), эта логика начинает дублироваться по всему проекту в местах, где вызывается
new; - становится сложно подменить реализацию в тестах (замокать) или изменить её в рантайме.
Порождающие паттерны инкапсулируют логику создания объектов в одном месте (метод, класс, отдельная фабрика), а остальной код работает с результатом через абстракцию, ничего не зная о том, как объект был создан.
Что объединяет паттерны из этой папки¶
| Паттерн | Ключевая идея |
|---|---|
| Singleton | Контролирует количество экземпляров - их должен быть ровно один |
| Factory Method | Откладывает выбор конкретного класса создаваемого объекта до подкласса |
| Abstract Factory | Создаёт согласованное семейство связанных объектов |
| Builder | Разделяет процесс сборки сложного объекта и его конечное представление |
| Prototype | Создаёт объект копированием готового прототипа, не зная его конкретного класса |
Когда об этой категории стоит вспомнить¶
- Логика выбора или сборки объекта содержит условия (
if/switchпо типу) и повторяется в разных местах кода. - Создание объекта требует много параметров, часть из которых опциональна.
- Нужно ограничить количество экземпляров класса (конфигурация, кеш, логгер).
- Система должна работать с разными семействами взаимосвязанных объектов (например, набор UI-контролов под разные темы), и важно не смешивать компоненты из разных семейств.
- Есть дорогие или сложно настроенные объекты, которые проще клонировать из готовых эталонов → Prototype.
Важная оговорка для .NET¶
Часть задач, которые в классическом ООП решались порождающими паттернами, в современном .NET закрываются стандартными механизмами платформы:
- DI-контейнер (
Microsoft.Extensions.DependencyInjection) во многом берёт на себя роль Factory/Abstract Factory и управление временем жизни объектов (в том числе Singleton-семантику черезAddSingleton); Lazy<T>упрощает ленивую инициализацию, на которой построен классический Singleton;- object initializers, именованные и опциональные параметры в конструкторах снижают потребность в Builder для простых случаев.
recordи выражениеwithдают удобный синтаксис неглубокого копирования, но не отменяют необходимость явно продумывать глубокую копию изменяемых ссылок в Prototype.
Тем не менее сами идеи (разделение "что создаём" и "как используем", сборка сложных объектов по шагам, семейства связанных объектов) остаются актуальными - меняется лишь конкретный синтаксис их выражения на C#.