Я собираю объяснение и пример кода этого шаблона проектирования, пытаясь помочь окружающим понять его (вместе с тем, помогая себе освоить шаблон).
Что я ищу, так это мнения и / или критика моего объяснения и примера кода ... спасибо!
Что такое заводской шаблон?
В фабричном шаблоне используется специальный выделенный «объект-создатель объекта» для управления созданием - и в большинстве случаев - созданием объектов, аналогично реальной фабрике.
Пример из реального мира
Представьте, что автомобильный завод является создателем различных типов автомобилей. Одна из сборочных линий на этом автомобильном заводе может производить грузовик однажды, но в другой день может быть переоборудован для производства автомобилей. Скажем, дилерский центр размещает заказ на 10 автомобилей в назначенном им отделе обработки счетов. Затем этот отдел использует определенный завод и заказывает 10 автомобилей. Обработчики аккаунтов не занимаются изготовлением автомобилей (представьте себе плохие результаты), они работают только с конечным продуктом, гарантируя, что автосалон получит их автомобили.
Новая модель того же автомобиля выйдет в следующем году, и начнут поступать заказы. Обработчики счетов (все еще не связанные с производством автомобиля) размещают заказы, но теперь автомобиль, который они получают, отличается, сборка Метод или даже может быть, фабрика в целом может отличаться, но обработчики учетных записей не должны беспокоиться об этом. Еще одна мысль: заводские сборщики транспортных средств могут точно знать, какое действие предпринять, если определенный обработчик счетов размещает заказ (т. Е. Обработчик счетов X размещает заказ, заводской сборщик знает, что для обработчика счетов X они производят 10 транспортных средств типа Y). ). Другой вариант может заключаться в том, что обработчик аккаунта сообщает ассемблеру, какой именно тип транспортного средства производить.
Если обработчики учетных записей также занимались созданием транспортных средств (т. Е. Они были связаны), каждый раз, когда транспортное средство каким-либо образом менялось, каждый из обработчиков учетных записей должен проходить переподготовку при производстве этого транспортного средства. Это создаст проблемы с качеством, так как обработчиков учетных записей будет гораздо больше, чем фабрики ... ошибки могут произойти, расходы будут намного выше.
Возвращаясь к ООП
Фабрика объектов в качестве шаблона проектирования, применяемого для разработки программного обеспечения, аналогична приведенному выше примеру в концепции… Фабрика производит различные типы других объектов, вы можете использовать сборочную линию (сборщик объектов), которая создает определенный тип объекта, возвращаемый в определенным образом. Ассемблер может либо проверить запрашивающий клиент и обработчик, либо клиент может сказать ассемблеру, какой объект ему требуется. Теперь ... вы работаете над проектом и создаете фабрику объектов и различные ассемблеры, позже в дальнейшем в проекте требования меняются незначительно, теперь вас просят изменить содержимое объекта и то, как его клиенты обрабатывают этот объект. Поскольку вы использовали фабричный шаблон, это простое изменение, и в одном месте вы можете изменить или добавить объекты, которые производит фабрика, и изменить формат, в котором ассемблеры выкладывают содержимое объекта.
Неудачный способ сделать это был бы без фабричного метода, создания экземпляра каждого экземпляра объекта и форматирования содержимого объекта в самих клиентах ... скажем, вы использовали этот конкретный объект в 20 клиентах. Теперь вы должны обратиться к каждому клиенту, изменить каждый из экземпляров и форматов объекта ... что за пустая трата времени ... Будьте ленивы ... сделайте это правильно с первого раза, чтобы сэкономить время себе (и другим) и усилия позже.
Пример кода (C #)
Ниже приведен пример использования фабрики для производства продуктов питания и различных пищевых объектов
Factory module
public enum FoodType
{
//enumerated foodtype value, if client wants to specify type of object, coupling still occurs
Hamburger, Pizza, HotDog
}
/// <summary>
/// Object to be overridden (logical)
/// </summary>
public abstract class Food
{
public abstract double FoodPrice { get; }
}
/// <summary>
/// Factory object to be overridden (logical)
/// </summary>
public abstract class FoodFactory
{
public abstract Food CreateFood(FoodType type);
}
//-------------------------------------------------------------------------
#region various food objects
class Hamburger : Food
{
double _foodPrice = 3.59;
public override double FoodPrice
{
get { return _foodPrice; }
}
}
class Pizza : Food
{
double _foodPrice = 2.49;
public override double FoodPrice
{
get { return _foodPrice; }
}
}
class HotDog : Food
{
double _foodPrice = 1.49;
public override double FoodPrice
{
get { return _foodPrice; }
}
}
#endregion
//--------------------------------------------------------------------------
/// <summary>
/// Physical factory
/// </summary>
public class ConcreteFoodFactory : FoodFactory
{
public override Food CreateFood(FoodType foodType)
{
switch (foodType)
{
case FoodType.Hamburger:
return new Hamburger();
break;
case FoodType.HotDog:
return new HotDog();
break;
case FoodType.Pizza:
return new Pizza();
break;
default:
return null;
break;
}
}
}
/// <summary>
/// Assemblers
/// </summary>
public class FoodAssembler
{
public string AssembleFoodAsString(object sender, FoodFactory factory)
{
Food food = factory.CreateFood(FoodType.Hamburger);
if (sender.GetType().Name == "default_aspx")
{
return string.Format("The price for the hamburger is: ${0}", food.FoodPrice.ToString());
}
else
{
return food.FoodPrice.ToString();
}
}
public Food AssembleFoodObject(FoodFactory factory)
{
Food food = factory.CreateFood(FoodType.Hamburger);
return food;
}
}
Calling factory
FoodFactory factory = new ConcreteFoodFactory(); //create an instance of the factoryenter code here
lblUser.Text = new FoodAssembler().AssembleFoodAsString(this, factory); //call the assembler which formats for string output
Object o = new FoodAssembler().AssembleFoodObject(factory); //example: instantiating anon object, initialized with created food object