我一起把这种设计模式的解释和代码示例,试图帮助我身边的人抓住它(与帮助自己掌握模式以及沿)。工厂设计模式(需要批判)
我所寻找的是意见&或批评我的解释和代码示例...谢谢!
什么是工厂模式? 工厂模式利用特定的专用“对象创建对象”来处理的创建 - 和最次的实例化 - 对象,类似于一个真正的世界工厂。
真实世界的例子
想想汽车工厂是各种类型的汽车的创造者。该汽车厂的其中一条生产线可能有一天会生产卡车,但在另一天可能会重新生产汽车。假设经销商向10个汽车订购了他们指定的账户处理部门。该部门然后利用某个工厂并订购了10辆汽车。账户处理人员并不关心自己制造汽车(想象一下效果不佳),他们只能使用最终产品,确保经销商获得他们的车辆。
下一年出现同一辆车的新车型,订单开始流入。帐户处理程序(仍然不关注汽车的生产)发出订单,但现在他们收到的车是不同的,组装方法甚至可能与工厂完全不同,但帐户处理人员不必担心这一点。另外一个想法:车辆的工厂装配可以知道,如果某帐户处理下定单采取什么动作(如帐户处理程序X下订单,工厂汇编知道帐户处理程序X,他们生产的Y型10辆)。另一种选择可能是账户处理程序告诉汇编程序究竟要生产什么类型的车辆。
如果帐户处理程序也处理创建车辆(即它们被耦合),则每次车辆以任何方式改变时,每个帐户处理程序将不得不重新训练以生产该车辆。这会产生质量问题,因为有更多的帐户处理程序比工厂会多......错误会发生,费用会更高。
盘旋回OOP
对象工厂应用于软件工程设计模式是类似于概念上述例子...工厂批量地生产出各种类型的其他的目的,可以利用一个流水线(对象汇编器),它产生一定的对象类型,以某种方式返回。汇编器可以检查请求的客户端并进行处理,或者客户端可以告诉汇编器它需要什么对象。现在......您正在创建一个项目并创建一个对象工厂和各种组装工具,稍后在项目的道路上,需求会稍有变化,现在要求您更改对象内容以及客户如何处理该对象。由于您使用了工厂模式,因此这是一个简单的更改,并且在一个位置,您可以更改或添加工厂生成的对象,并更改汇编器放置对象内容的格式。
不幸的方式这样做本来是没有一个工厂方法,每个实例化对象实例和格式化对象的内容在客户端本身...说你在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
社区wiki,也许? – 2010-11-04 18:39:32
为何选择近距离投票?问题是有效的,虽然它有点长:) – jgauffin 2010-11-04 19:13:49