Порождающие паттерны: «Фабричный метод» (Factory Method)
                        
                    Назначение: определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать. Фабричный метод позволяет классу делегировать инстанцирование подклассам.
Когда следует использовать фабричный метод
- Когда заранее неизвестно, объекты каких типов необходимо создавать;
 - Когда система должна быть независимой от процесса создания новых объектов и расширяемой: в нее можно легко вводить новые классы, объекты которых система должна создавать;
 - Когда создание новых объектов необходимо делегировать из базового класса классам наследникам;
 
Схема примера использования паттерна "Фабричный метод" из реальной жизни:

UML схема паттерна фабричный метод

Реализация шаблона "фабричный метод" на C#
using System;
 
namespace DoFactory.GangOfFour.Factory.Structural
{
  class MainApp
  {
 
    static void Main()
    {
      // An array of creators
      Creator[] creators = new Creator[2];
 
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();
 
      // Iterate over creators and create products
      foreach (Creator creator in creators)
      {
        Product product = creator.FactoryMethod();
        Console.WriteLine("Created {0}",
          product.GetType().Name);
      }
 
      // Wait for user
      Console.ReadKey();
    }
  }
  abstract class Product
  {
  }
  class ConcreteProductA : Product
  {
  }
 
  class ConcreteProductB : Product
  {
  }
 
  abstract class Creator
  {
    public abstract Product FactoryMethod();
  }
  class ConcreteCreatorA : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductA();
    }
  }
 
  class ConcreteCreatorB : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductB();
    }
  }
}Output
Created ConcreteProductA
Created ConcreteProductBОбсуждение паттерна «Фабричный метод»
У каждой реализации фабричного метода есть свои особенности
- Классический фабричный метод является частным случаем шаблонного метода. Это значит, что фабричный метод привязан к текущей иерархии типов и не может быть использован повторно в другом контексте.
 - Полиморфный фабричный метод является стратегией создания экземпляров некоторого семейства типов, что позволяет использовать одну фабрику в разных контекстах. Тип создаваемого объекта определяется типом фабрики и обычно не зависит от аргументов фабричного метода.
 - Статический фабричный метод является самой простой формой фабричного метода. Статический метод создания позволяет обойти ограничения конструк- торов. Например, тип создаваемого объекта может зависеть от аргументов ме- тода, экземпляр может возвращаться из кэша, а не создаваться заново или же фабричный метод может быть асинхронным.
 
Использование Func в качестве фабрики
В некоторых случаях Func может использоваться в качестве полноценной фабрики и передаваться классу извне его клиентами. Данный вариант фабрики является допустимым во внутреннем (internal) коде и только для функций с небольшим количеством аргументов. Понять, что делает Func, довольно просто, но разобраться в назначении Func<int, string, int, ValidationResult> factory без контекста будет практически невозможно.Читаемость кода очень важна, поэтому именованная фабрика является предпочтительным вариантом.
Конструктор vs. фабричный метод
В объектно-ориентированных языках программирования конструктор отвечает за корректную инициализацию создаваемого объекта. В большинстве случаев они прекрасно справляются со своей задачей, но иногда лучше воспользоваться статическим фабричным методом.
Именованные конструкторы.
В языке C# имя конструктора совпадает с именем класса, что делает невозможным использование двух конструкторов с одним набором и типом параметров. Хорошим примером такого ограничения является структура Timespan, которая представляет собой интервал времени. Очень удобно создавать интервал времени по количеству секунд, минут, часов и дней, но сделать несколько конструкторов, каждый из которых принимает один параметр типа double, невозможно. Для этого структура Timespan содержит набор фабричных методов (пример ниже)
public struct Timespan
{
 public Timespan(double ticks) { ... }
 public static Timespan FromMilliseoncds(double value) {...}
 public static Timespan FromSeconds(double value) {...}
 public static Timespan FromMinutes(double value) {...}
}Тяжеловесный процесс создания
Конструктор отвечает за корректную инициализацию объекта, после которой объект должен быть готов для использования своими клиентами. Обычно логика инициализации относительно простая и должна выполняться конструктором, но слишком тяжеловесную логику лучше вынести из конструктора в статический фабричный метод
Примеры в .NET Framework
В .NET Framework применяется огромное количество фабрик.
- Классический фабричный метод: Stream.CreateWaitHandle, SecurityAttribute.CreatePermission, ChannelFactory.CreateChannel, XmlNode.CreateNavigator.
 - Полиморфная фабрика: IControllerFactory в ASP.NET MVC, IHttpHandlerFactory в ASP.NET, ServiceHostFactory и IChannelFactory в WCF, IQueryProvider в LINQ.
 - Неполиморфная фабрика: TaskFactory в TPL.
 - Обобщенная статическая фабрика: Activator.CreateInstance, Array.CreateInstance, StringComparer.Create.
 - Сокрытие наследников: RandomNumberGenerator.Create, WebRequest.Create, BufferManager.CreateBufferManager, Message.CreateMessage, MessageFault.CreateFault
 - Фасадные фабричные методы: File.Create, File.CreateText.
 - Именованные конструкторы: Timespan.FromSecond, Timespan.FromMilliseconds, GCHandle.FromIntPtr, Color.FromArgb.