我正在整理这个设计模式的解释和代码示例,试图帮助我周围的人理解它(同时也帮助我自己掌握模式)。
工厂的模式是什么?
工厂模式使用一个特定的专用“对象创建器对象”来处理对象的创建(大多数情况下是对象的实例化),类似于真实的工厂。
想象一下汽车工厂是各种汽车的创造者。那家汽车厂的一条装配线可能有一天会生产一辆卡车,但另一天可能会重新加工生产汽车。假设经销商向其指定的客户处理部门订购了10辆车。然后那个部门利用某个工厂订购10辆车。客户经理并不关心汽车本身的制造(想象一下糟糕的结果),他们只处理最终产品,确保经销商得到他们的汽车。
同一款车的一款新车型将于明年面世,订单开始源源不断地涌入。会计人员(仍然不关心汽车的生产)下订单,但是现在他们收到的汽车不同了,装配方法甚至工厂可能完全不同了,但是会计人员不必担心这一点。另一个想法是:如果某个客户处理程序下了订单,车辆的工厂装配工可能确切知道该采取什么行动(即,客户处理程序X下了订单,工厂装配工知道,对于客户处理程序X,他们生产10辆Y型车辆)。另一种选择可能是,帐户处理程序告诉汇编程序要生成哪种类型的车辆。
如果账户处理人也处理车辆的创建(即它们是耦合的),则每次车辆以任何方式改变时,每个账户处理人都必须在生产该车辆时接受再培训。这会造成质量问题,因为会计处理人员比工厂多得多……错误会发生,费用会大得多。
对象工厂作为一种应用于软件工程的设计模式,在概念上类似于上面的例子工厂生产出各种类型的其他对象,您可以使用一个生产某种对象类型的装配线(对象装配器),以某种方式返回。汇编程序可以检查请求的客户机并进行处理,或者客户机可以告诉汇编程序它需要什么对象。现在…您正在一个项目中创建一个对象工厂和各种汇编器,稍后在项目中,需求会稍微改变,您现在被要求更改对象内容及其客户机如何处理该对象。由于使用了工厂模式,这是一个简单的更改,在一个位置,您可以更改或添加工厂生成的对象,并更改汇编器布局对象内容的格式。
代码示例(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