TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #445 826
День триста семьдесят третий. #DesignPatterns
Паттерны проектирования
12. Паттерн «Фабричный метод» (Factory Method)
Когда при обсуждении дизайна упоминается фабрика, то в подавляющем большинстве случаев имеется в виду одна из разновидностей паттерна «Фабричный метод».

Назначение: определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс создавать. Фабричный метод позволяет классу делегировать создание объекта подклассам.

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

На практике встречаются три вида паттерна «Фабричный метод», которые приведены на рисунке ниже:
- Creator — объявляет абстрактный или виртуальный метод создания продукта, использует фабричный метод в своей реализации;
- ConcreteCreator — реализует фабричный метод, который возвращает ConcreteProduct;
- Product — определяет интерфейс продуктов, создаваемых фабричным методом;
- ConcreteProduct — определяет конкретный вид продуктов.

1. Классический фабричный метод является частным случаем паттерна «Шаблонный метод», переменный шаг которого отвечает за создание нужного типа объекта. Это значит, что фабричный метод привязан к текущей иерархии типов и не может быть использован повторно в другом контексте.

2. Статический фабричный метод является самой простой версией. Основное отличие его от классического в том, что тип создаваемого объекта определяется не типом наследника, а аргументами, переданными методу. Типичная реализация такого метода содержит оператор switch, в котором происходит выбор создаваемого типа. Вместо этого можно воспользоваться словарём, ключом которого будет некоторый идентификатор (строка, перечисление и т. п.), а значением — делегат, который будет создавать объект нужного класса. Статический метод позволяет обойти ограничения конструкторов. Например, тип создаваемого объекта может зависеть от аргументов метода, экземпляр может возвращаться из кэша, а не создаваться заново или же фабричный метод может быть асинхронным.

3. Полиморфный фабричный метод определяет интерфейс фабрики, а за создание конкретного экземпляра продукта отвечает конкретная фабрика. Является стратегией создания экземпляров некоторого семейства типов, что позволяет использовать одну фабрику в разных контекстах. Тип создаваемого объекта определяется типом фабрики и обычно не зависит от аргументов фабричного метода.

Конструктор vs. фабричный метод
В большинстве случаев конструкторы прекрасно справляются со своей задачей. Но есть две причины использовать фабричный метод вместо конструктора:
1. Именованные конструкторы. В языке C# невозможно использовать два конструктора с одним набором и типом параметров. Хорошим примером такого ограничения является структура Timespan. Очень удобно создавать интервал времени по количеству секунд, минут, часов и дней, но сделать несколько конструкторов, каждый из которых принимает один параметр типа double, невозможно. Для этого структура Timespan содержит набор фабричных методов.
public struct Timespan {
public Timespan(double ticks) {…}
public static Timespan FromMilliseconds(double value) {…}
public static Timespan FromSeconds(double value) {…}
public static Timespan FromMinutes(double value) {…}
…
}

2. Тяжеловесный процесс создания. Обычно логика конструктора относительно простая, но слишком тяжеловесную логику лучше вынести в статический фабричный метод. Если для конструирования объекта требуется обращение к внешним ресурсам, то лучше сразу же выделять эту логику в фабричный метод. Это позволяет сделать фабричный метод асинхронным, а также упростить эволюцию решения и разбиение данного класса на более мелкие составляющие в случае необходимости.

Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 10.
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →