C# 工厂设计模式(需要评论)
我正在整理这个设计模式的解释和代码示例,试图帮助我周围的其他人掌握它(同时帮助我自己掌握这个模式) 我想要的是对我的解释和代码示例的意见和批评……谢谢 工厂模式是什么? 工厂模式利用一个特定的专用“对象创建者对象”来处理对象的创建,大多数情况下是对象的实例化,类似于真实世界的工厂 真实世界示例C# 工厂设计模式(需要评论),c#,design-patterns,factory-pattern,C#,Design Patterns,Factory Pattern,我正在整理这个设计模式的解释和代码示例,试图帮助我周围的其他人掌握它(同时帮助我自己掌握这个模式) 我想要的是对我的解释和代码示例的意见和批评……谢谢 工厂模式是什么? 工厂模式利用一个特定的专用“对象创建者对象”来处理对象的创建,大多数情况下是对象的实例化,类似于真实世界的工厂 真实世界示例 想象一下,汽车工厂是各种汽车的创造者。那家汽车厂的一条装配线可能有一天会生产一辆卡车,但另一天可能会重新加工以生产汽车。假设经销商向其指定的客户处理部门下了10辆车的订单。该部门随后利用某个工厂订购了10
想象一下,汽车工厂是各种汽车的创造者。那家汽车厂的一条装配线可能有一天会生产一辆卡车,但另一天可能会重新加工以生产汽车。假设经销商向其指定的客户处理部门下了10辆车的订单。该部门随后利用某个工厂订购了10辆汽车。客户经理不关心自己生产汽车(想象一下糟糕的结果),他们只处理最终产品,确保经销商得到他们的汽车 同一辆车的新型号第二年问世,订单开始源源不断。客户经理(仍然不关心汽车的生产)下订单,但现在他们收到的汽车不同了,装配方法甚至工厂可能完全不同,但客户经理不必担心这一点。另外一个想法是:如果某个客户处理人下订单,车辆的工厂装配工可能确切知道要采取什么行动(即客户处理人X下订单,工厂装配工知道,对于客户处理人X,他们生产10辆Y型车辆)。另一种选择可能是,帐户处理程序确切地告诉装配工要生产什么类型的车辆 如果客户经办人也处理车辆的创建(即,它们是耦合的),则每次车辆以任何方式发生变化时,每个客户经办人都必须在生产该车辆时接受再培训。这将产生质量问题,因为会计处理人员的数量远远超过工厂的数量……错误会发生,费用会大得多 循环返回OOP
对象工厂作为一种应用于软件工程的设计模式,在概念上类似于上面的示例……工厂大量生产各种类型的其他对象,您可以利用一条生产线(对象汇编程序),该生产线生产以某种方式返回的特定对象类型。汇编程序可以检查请求的客户机并进行处理,或者客户机可以告诉汇编程序它需要什么对象。现在…您正在一个项目中创建一个对象工厂和各种汇编程序,稍后在项目中,需求会略有变化,您现在被要求更改对象内容及其客户机如何处理该对象。由于使用了factory模式,这是一个简单的更改,在一个位置,您可以更改或添加factory生成的对象,并更改汇编器布局对象内容的格式 不幸的是,如果没有工厂方法的话,那么就没有工厂方法,实例化每个对象实例并在客户机本身中格式化对象内容……假设您在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
工厂模块
公共枚举FoodType
{
//枚举的foodtype值,若客户端希望指定对象的类型,则仍会发生耦合
汉堡包、比萨饼、热狗
}
///
///要重写的对象(逻辑)
///
公共抽象类食品
{
公共摘要双食品价格{get;}
}
///
///要重写的工厂对象(逻辑)
///
公共抽象类FoodFactory
{
公共抽象食品CreateFood(FoodType类型);
}
//-------------------------------------------------------------------------
#区域各种食物对象
班级:汉堡:食物
{
双食品价格=3.59;
公共覆盖双食物价格
{
获取{return\u foodPrice;}
}
}
班级比萨饼:食物
{
双食品价格=2.49;
公共覆盖双食物价格
{
获取{return\u foodPrice;}
}
}
班级热狗:食物
{
双食品价格=1.49;
公共覆盖双食物价格
{
获取{return\u foodPrice;}
}
}
#端区
//--------------------------------------------------------------------------
///
///实体工厂
///
公共类ConcreteFoodFactory:FoodFactory
{
公共覆盖食品CreateFood(FoodType FoodType)
{
开关(foodType)
{
case FoodType.汉堡:
退回新汉堡包();
打破
case FoodType.HotDog:
返回新的热狗();
打破
case FoodType.Pizza:
归还新比萨饼();
打破
违约:
返回null;
打破
}
}
}
///
///汇编程序
///
公共级食品装配工
{
公共字符串AssembleFoodAsString(对象发送方,FoodFactory工厂)
{
Food=factory.CreateFood(FoodType.Hamburger);
if(sender.GetType().Name==“default\u aspx”)
{
public interface IFood
{
bool IsTasty { get; }
}
public class Hamburger : IFood
{
public bool IsTasty {get{ return true;}}
}
public class PeaSoup : IFood
{
public bool IsTasty { get { return false; } }
}
public class FoodFactory
{
private Dictionary<string, Type> _foundFoodTypes =
new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Scan all specified assemblies after food.
/// </summary>
public void ScanForFood(params Assembly[] assemblies)
{
var foodType = typeof (IFood);
foreach (var assembly in assemblies)
{
foreach (var type in assembly.GetTypes())
{
if (!foodType.IsAssignableFrom(type) || type.IsAbstract || type.IsInterface)
continue;
_foundFoodTypes.Add(type.Name, type);
}
}
}
/// <summary>
/// Create some food!
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public IFood Create(string name)
{
Type type;
if (!_foundFoodTypes.TryGetValue(name, out type))
throw new ArgumentException("Failed to find food named '" + name + "'.");
return (IFood)Activator.CreateInstance(type);
}
}
var factory = new FoodFactory();
factory.ScanForFood(Assembly.GetExecutingAssembly());
Console.WriteLine("Is a hamburger tasty? " + factory.Create("Hamburger").IsTasty);