加入收藏

【23种设计模式】工厂方法模式(二)

2023-08-28 22:49:48 来源:博客园

****## 前言

在讲述之工厂方法模式前,我们来先了解简单工厂模式,简单工厂模式是最简单的设计模式之一,它虽然不属于GoF的23种设计模式,但是应用也较为频繁,同时它也是学习其他创建型模式的基础。下面我们来先了解下简单工厂模式,然后针对它的缺点来引出工厂方法模式。

简单工厂模式定义

简单工厂模式简单来说就是创建一个工厂类,通过输入的参数创建对象赋值给基类,完成对想要的派生类的调用,从而达成目标,具体的操作均在子类中完成,工厂类只负责运算逻辑和给基类赋值。在简单工厂模式中,只需要记住一个简单的参数即可获得所需的对象实例,它提供专门的核心工厂类来负责对象的创建,实现对象的创建和使用分离。该模式有三部分:


【资料图】

  • 工厂方法类:实现创建所有实例的选择类型,被外界调用的接口。
  • 抽象父类:所要创建的类的基类,描述类所有实例所共有的公共接口(方法),可以是抽象类也可是接口类型(interface),本例是抽象类。
  • 具体子类:所有要创建的具体实例对象。

简单工厂模式代码实现

抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中,根据不同的参数创建不同类型的产品子类对象。只需要添加配置文件并更改相关参数读取参数即可,不要重新编译程序。

  • 引入NuGet包:System.Configuration.ConfigurationManager

  • 添加配置文件:App.config文件,追加内容

  • 创建抽象父类和具体子类抽象类:包含工厂方法

    ///     /// 【01】抽象工厂类    ///     public abstract class Product    {        ///         /// 静态工厂方法        ///         ///         ///         public static Product GetProduct(string arg)        {            Product product = null;            switch (arg)            {                case "A":                    product = new ProduceA();                    break;                case "B":                    product = new ProduceB();                    break;                    //注意:有新产品需要修改工厂方法和创建新具体产品                default:                    throw new ArgumentException(message: "参数不合法");            }            return product;        }        ///         /// 所有产品类的公共业务方法        ///         public void MethodSame()        {            Console.WriteLine("公共业务方法");        }        ///         /// 声明抽象业务方法        ///         public abstract void MethodDiff();    }

    具体子类:

    ///     ///【02】具体工厂类A    ///     public class ProduceA : Product    {        ///         /// 实现业务方法        ///         public override void MethodDiff()        {            Console.WriteLine("产品A处理业务方法");        }    }
    ///     ///【03】具体工厂类B    ///     public class ProduceB : Product    {        ///         /// 实现业务方法        ///         public override void MethodDiff()        {            Console.WriteLine("产品B处理业务方法");        }    }
  • 调用

    ///         /// 调用测试方法        ///         public void RunTest()        {            //客户端调用            var type = ConfigurationManager.AppSettings["product"];//根据配置文件中参数,传入工厂方法,决定创建具体Product            Product oneProduct = Product.GetProduct(type);            oneProduct.MethodSame();            oneProduct.MethodDiff();        }

简单工厂模式的优缺点

优点:

  • 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,
  • 简单工厂模式实现了对象创建和使用的分离。
  • 客户端无须知道所创建的具体产品类的类名,只需知道具体产品类所对应的参数即可。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下,更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

  • 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式势必会增加系统中类的个数,增加了系统的复杂度和理解难度。
  • 系统扩展难度,一旦添加新产品不得不修改工厂逻辑,在产品类型加多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展与维护。
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

简单工厂模式小结

简单工厂模式中,我们也发现了它的缺点,就是随着需求的变化我们要不停地修改工厂里面的方法的代码,需求变化越多,里面的If–Else–也越多,这样就会造成简单工厂的实现逻辑过于复杂。设计模式是遵循一定原则而得来的,比如,我们要怎么增加代码,怎么修改代码,其中一个原则就是OCP原则,中文是【开放关闭原则】,对增加代码开放,对修改代码关闭,所以我们就不能总是这样修改简单工厂里面的方法。

工厂方法模式定义

工厂方法模式可以解决简单工厂模式中存在的这个问题,定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。

可以看出,在工厂方法模式的结构图有以下角色:

  • 抽象工厂(Creator): 充当抽象工厂角色,定义工厂类所具有的基本的操作,任何具体工厂都必须继承该抽象类。

  • 具体工厂(CreatorA):充当具体工厂角色,该类必须继承抽象工厂角色,实现抽象工厂定义的方法,用来创建具体车。

  • 抽象车(Car):充当抽象车角色,定义车类型所有具有的基本操作,具体车必须继承该抽象类。

  • 具体车(CarA):充当具体车角色,实现抽象车类对定义的抽象方法,由具体工厂类创建,它们之间有一一对应的关系。

简单工厂模式的问题是:如果有新的需求,就需要修改工厂类里面创建产品对象实例的那个方法的实现代码,在面向对象设计一个原则就是哪里有变化,我就封装哪里。

工厂方法模式代码实现

  • 抽象汽车类

    ///     /// 汽车抽象类    ///     public abstract class Car    {        ///         /// 开始行驶        ///         public abstract void Go();    }
  • 具体汽车类

    ///     /// ConcreteCar 具体车辆类    ///     public class ConcreteCar    {        ///         /// 红旗汽车        ///         public class HongQiCar : Car        {            public override void Go()            {                Console.WriteLine("红旗汽车开始行驶了!");            }        }        ///         /// 奥迪汽车        ///         public class AoDiCar : Car        {            public override void Go()            {                Console.WriteLine("奥迪汽车开始行驶了");            }        }    }
  • 抽象工厂

    ///     /// 抽象工厂类    ///     public abstract class Factory    {        ///         /// 工厂方法        ///         ///         public abstract Car CreateCar();    }
  • 具体工厂

    ///     /// ConcreteFactory  具体工厂方法    ///     public class ConcreteFactory    {        ///         /// 红旗汽车工厂类        ///         public class HongQiCarFactory : Factory        {            ///             /// 负责生产红旗汽车            ///             ///             public override Car CreateCar()            {                return new HongQiCar();            }        }        ///         /// 奥迪汽车工厂类        ///         public class AoDiCarFactory : Factory        {            ///             /// 负责创建奥迪汽车            ///             ///             public override Car CreateCar()            {                return new AoDiCar();            }        }    }
  • 调用

    ///         /// 测试方法        ///         public void RunTest()        {            // 初始化创建汽车的两个工厂            Factory hongQiCarFactory = new HongQiCarFactory();            Factory aoDiCarFactory = new AoDiCarFactory();            // 生产一辆红旗汽车            Car hongQi = hongQiCarFactory.CreateCar();            hongQi.Go();            //生产一辆奥迪汽车            Car aoDi = aoDiCarFactory.CreateCar();            aoDi.Go();        }

工厂方法模式优缺点

优点:

  • 在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
  • 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。

缺点:

  • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

关键词:

相关新闻

资讯

八项规定是哪八项
八项规定是哪八项

领导干部廉政约束规定是指对党员领导干部廉政行为规范......更多>

地方高校新文科建设应精准施策靶向发力
地方高校新文科建设应精准施策靶向发力

新文科建设始于2018年,至今已走过5年历程。当前,一......更多>

“五连涨”要来了?国内成品油调价悬念仍存
“五连涨”要来了?国内成品油调价悬念仍存

中新经纬8月23日电(付健青)23日24时,国内成品油新一......更多>

阿维塔11鸿蒙版SUV上市,价格诱人 动力强大
阿维塔11鸿蒙版SUV上市,价格诱人 动力强大

阿维塔11鸿蒙版SUV正式上市,共推出四款车型,价格区......更多>

比亚迪入股模拟和混合信号IC设计企业芯进电子
比亚迪入股模拟和混合信号IC设计企业芯进电子

8月28日,记者查询天眼查发现,近日,成都芯进电子有......更多>

重庆14个区县出现暴雨 73条中小河流出现1~6米涨水过程
重庆14个区县出现暴雨 73条中小河流出现1~6米涨水过程

据重庆市水文监测总站监测,昨(26)日8时至今(27)......更多>

iQOO Z8系列官宣搭载零感蓝光原彩屏 全系通过SGS认证
iQOO Z8系列官宣搭载零感蓝光原彩屏 全系通过SGS认证

【手机中国新闻】iQOOZ8系列将于8月31日晚正式发布。......更多>

江宁爱情隧道最佳时间(江宁爱情隧道)
江宁爱情隧道最佳时间(江宁爱情隧道)

1、在江宁区正方中路那边,是往云台山去的小铁路,公......更多>

氛围拉满!亚运会,杭州准备好了
氛围拉满!亚运会,杭州准备好了

氛围拉满!亚运会,杭州准备好了,座席,电子票,售票亭,......更多>

美媒:日本国际形象“污”了
美媒:日本国际形象“污”了

美媒:日本国际形象“污”了...更多>

关注

淘宝网页版(逃吧)
淘宝网页版(逃吧)
来为大家解答以上问题,淘宝网页版,逃吧很多人还不知... 更多>
淘宝网页版(逃吧)
来为大家解答以上问题,淘宝网页版,逃吧很多人还不知... 更多>
受降雨影响,河南多条高速实施管制
据央视新闻,中国铁路郑州局集团有限公司消息,受各地... 更多>
2023广东(廉江)乡村休闲产业招商推介大会举办
近日,2023广东(廉江)乡村休闲产业招商推介大会在廉... 更多>
梦见异性朋友是什么意思
梦见异性朋友通常表示一种无形的吸引力或者是你对这个... 更多>
临汾市深入推进矿山企业“体检式”精查工作
临汾市深入推进矿山企业“体检式”精查工作,主流媒体,... 更多>
艺术体操世锦赛:中国队历史性首夺金牌 1金2银完美收官
人民网北京8月28日电(记者李乃妍)北京时间8月28日凌晨... 更多>
国信证券给予星宇股份买入评级,二季度营收超越汽车行业,经营拐点已现
国信证券08月28日发布研报称,给予星宇股份(601799 ... 更多>
类银河恶魔城横板动作续作《尘埃异变2》首发预告
CloverBite发布了新发布的类银河恶魔城动作游戏续作《... 更多>
《博德之门3》幽暗地域传送点位置汇总 幽暗地域传送点在哪?
博德之门3有很多传送点可以进入幽暗地域,那么这些传... 更多>
刑事公诉案件证据不足如何处理好
刑事公诉案件证据不足,如果在侦查阶段,公安认为证据... 更多>
从机器人博览会观察前沿技术和产业发展 我国机器人产业迈向中高端
前不久,在北京举办的2023世界机器人大会机器人博览会... 更多>
研究发现对于手臂骨折的老年人来说 石膏与手术一样有效
《骨科研究杂志》最近的一项研究发现,对于治疗手腕附... 更多>