工厂设计模式(求批评)我正在整理这个设计模式的讲解和代码示例,试图帮助周围的人抓住它(同时帮助自己掌握图案)。我正在寻找的是对我的解释和代码示例的评论和批评......谢谢!什么是工厂模式?工厂模式利用特定的专用“对象创建者对象”来处理对象的创建——并在大部分时间实例化对象,类似于现实世界的工厂。现实世界的例子想象一家汽车工厂是各种类型汽车的制造商。汽车厂的装配线可能有一天会生产一辆卡车,但另一天会把它变成一辆汽车。假设一家经销商向其指定的账户处理部门下了10辆汽车的订单。该部门然后利用某个工厂并订购了10辆汽车。客户处理人员不关心自己制造汽车(想象效果不佳),他们只处理最终产品,确保经销商得到他们的车辆。同款车明年出现新车型,订单开始源源不断涌入。客户(仍然不关心汽车的生产)下订单,但现在他们收到的汽车不同,组装方法甚至工厂可能有所不同,但帐户处理程序不必担心。另一个想法:车辆的工厂组装可能确切地知道如果某个帐户处理器下订单(即帐户处理器X下订单,工厂组装知道帐户处理器X,他们生产10辆Y的车辆)型车辆)。另一种选择可能是让帐户处理程序准确地告诉装配商要生产哪种类型的车辆。如果帐户处理程序还处理车辆的创建(即它们是耦合的),则无论何时车辆以任何方式发生变化,都必须在生产该车辆时重新培训每个帐户处理程序。这会造成质量问题,因为客户处理人员比工厂多……会发生错误,成本也会更高。回到OOP对象工厂作为一种应用于软件工程的设计模式在概念上类似于上面的例子......工厂生成其他各种类型的对象,你可以利用生成某种对象类型的装配线(objectassembler),返回以某种方式。汇编程序可以检查请求的客户端和句柄,或者客户端可以告诉汇编程序它想要什么对象。现在...您正在处理一个项目并创建一个对象工厂和各种装配器,在项目的后期,需求发生了一些变化,现在需要您更改对象内容以及客户端处理该对象的方式。由于您使用的是工厂模式,因此这是一个简单的更改,您可以在一个地方更改或添加工厂生成的对象,并更改汇编程序放置对象内容的格式。不幸的是没有工厂方法,实例化每个对象实例并在客户端本身格式化对象内容……假设您在20个客户端中使用这个特定对象。现在你必须去每个客户端并更改每个对象实例和格式......浪费时间......懒惰......第一次就以正确的方式做,这样你就可以节省自己(和其他人)的时间并在以后努力工作。代码显示示例(C#)下面是利用工厂生产的食品和各种食品的示例FactorymodulepublicenumFoodType{//枚举的foodtype值,如果client要指定对象的类型,仍然会发生耦合Hamburger,Pizza,HotDog}/////要覆盖的对象(逻辑)///publicabstractclassFood{publicabstractdoubleFoodPrice{get;}}//////要覆盖的工厂对象(逻辑)///publicabstractclassFoodFactory{publicabstractFoodCreateFood(FoodTypetype);}//----------------------------------------------------------------------#region各种食物对象类Hamburger:Food{double_foodPrice=3.59;publicoverridedoubleFoodPrice{get{return_foodPrice;}}}类披萨:食物{double_foodPrice=2.49;publicoverridedoubleFoodPrice{get{return_foodPrice;}}}classHotDog:Food{double_foodPrice=1.49;publicoverridedoubleFoodPrice{get{return_foodPrice;}}}#endregion//----------------------------------------------------------------------//////物理工厂///publicclassConcreteFoodFactory:FoodFactory{publicoverrideFoodCreateFood(FoodTypefoodType){switch(foodType){caseFoodType.Hamburger:returnnewHamburger();休息;caseFoodType.HotDog:返回新的HotDog();休息;caseFoodType.Pizza:returnnewPizza();休息;默认值:返回空值;休息;}}}//////组装器///publicclassFoodAssembler{publicstringAssembleFoodAsString(objectsender,FoodFactoryfactory){Foodfood=factory.CreateFood(FoodType.Hamburger);if(sender.GetType().Name=="default_aspx"){returnstring.Format("汉堡包的价格是:${0}",food.FoodPrice.ToString());}else{返回food.FoodPrice.ToString();}}publicFoodAssembleFoodObject(FoodFactoryfactory){Foodfood=factory.CreateFood(FoodType.Hamburger);退回食物;}}调用工厂FoodFactoryfactory=newConcreteFoodFactory();//创建一个实例工厂在此处输入代码lblUser.Text=newFoodAssembler().AssembleFoodAsString(this,factory);//调用格式化字符串输出的汇编器Objecto=newFoodAssembler().AssembleFoodObject(factory);//示例:实例化anon对象,用创建的食物对象初始化抱歉,这是一种非常不可思议的植物。反射可以给一些POWWAH!!公共接口IFood{boolIsTasty{get;}}publicclassHamburger:IFood{publicboolIsTasty{get{returntrue;}}}publicclassPeaSoup:IFood{publicboolIsTasty{get{returnfalse;}}}publicclassFoodFactory{privateDictionary_foundFoodTypes=newDictionary(StringComparer.OrdinalIgnoreCase);//////食物后扫描所有指定的程序集。///publicvoidScanForFood(paramsAssembly[]assemblies){varfoodType=typeof(IFood);foreach(varassemblyinassemblys){foreach(vartypeinassembly.GetTypes()){if(!foodType.IsAssignableFrom(type)||type.IsAbstract||type.IsInterface)继续;_foundFoodTypes.Add(类型。名称,类型);}}}//////创造一些食物!/////////publicIFoodCreate(stringname){类型类型;if(!_foundFoodTypes.TryGetValue(name,outtype))thrownewArgumentException("Failedtofindfoodnamed'"+name+"'.");返回(IFood)Activator.CreateInstance(类型);}}用法:varfactory=newFoodFactory();factory.ScanForFood(Assembly.GetExecutingAssembly());Console.WriteLine("汉堡包好吃吗?"+factory.Create("汉堡包").IsTasty);编辑,对您的代码提供反馈:首先,当添加新类型的实现以进行更新时,工厂习惯于能够以尽可能少的代码更改创建对象。当然,它仍然比直接创建类型要好一些。您的代码的第二个问题是您使用的是switch语句(但如果您需要枚举,这是最好的方法)。能够以某种方式注册所有不同的类会更好。从配置文件或允许实际实现(例如Hamburger类)自行注册。这就需要工厂遵循单例模式。以下是对救援的思考。反射允许您迭代DLL和EXE中的所有类型。因此,我们可以搜索所有实现我们接口的类,从而能够构建所有类的字典。我认为你的解释包括真实世界的例子很好。但是,我不认为您的示例代码显示了该模式的真正好处。一些可能的变化:我建议您使用接口而不是抽象类/继承。除此之外,它看起来还不错。以上就是《C#学习教程:工厂设计模式(待批)》分享的全部内容。侵权请点击右侧联系管理员删除。如需转载请注明出处:
