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);