论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
后端开发
›
.Net
›
【23种设计模式】工厂方法模式(二)
【23种设计模式】工厂方法模式(二)
铁佛
金牌会员
|
2023-9-1 20:44:14
|
显示全部楼层
|
阅读模式
楼主
主题
882
|
帖子
882
|
积分
2646
****## 前言
在讲述之工厂方法模式前,我们来先了解简单工厂模式,简单工厂模式是最简单的设计模式之一,它虽然不属于GoF的23种设计模式,但是应用也较为频繁,同时它也是学习其他创建型模式的基础。下面我们来先了解下简单工厂模式,然后针对它的缺点来引出工厂方法模式。
简单工厂模式定义
简单工厂模式
简单来说就是创建一个工厂类,通过输入的参数创建对象赋值给基类,完成对想要的派生类的调用,从而达成目标,具体的操作均在子类中完成,工厂类只负责运算逻辑和给基类赋值。在简单工厂模式中,
只需要记住一个简单的参数即可获得所需的对象实例,它提供专门的核心工厂类来负责对象的创建,实现对象的创建和使用分离
。该模式有三部分:
工厂方法类
:实现创建所有实例的选择类型,被外界调用的接口。
抽象父类:
所要创建的类的基类,描述类所有实例所共有的公共接口(方法),可以是抽象类也可是接口类型(interface),本例是抽象类。
具体子类:
所有要创建的具体实例对象。
简单工厂模式代码实现
抽象产品类和工厂类合并,将静态工厂方法移到抽象产品类中,根据不同的参数创建不同类型的产品子类对象。只需要添加配置文件并更改相关参数读取参数即可,不要重新编译程序。
引入NuGet包:System.Configuration.ConfigurationManager
添加配置文件:App.config文件,追加内容
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Product" value="B" />
</appSettings>
</configuration>
复制代码
创建抽象父类和具体子类
抽象类:包含工厂方法
/// <summary>
/// 【01】抽象工厂类
/// </summary>
public abstract class Product
{
/// <summary>
/// 静态工厂方法
/// </summary>
/// <param name="arg"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 所有产品类的公共业务方法
/// </summary>
public void MethodSame()
{
Console.WriteLine("公共业务方法");
}
/// <summary>
/// 声明抽象业务方法
/// </summary>
public abstract void MethodDiff();
}
复制代码
具体子类:
/// <summary>
///【02】具体工厂类A
/// </summary>
public class ProduceA : Product
{
/// <summary>
/// 实现业务方法
/// </summary>
public override void MethodDiff()
{
Console.WriteLine("产品A处理业务方法");
}
}
复制代码
/// <summary>
///【03】具体工厂类B
/// </summary>
public class ProduceB : Product
{
/// <summary>
/// 实现业务方法
/// </summary>
public override void MethodDiff()
{
Console.WriteLine("产品B处理业务方法");
}
}
复制代码
调用
/// <summary>
/// 调用测试方法
/// </summary>
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)
:充当具体车角色,实现抽象车类对定义的抽象方法,由具体工厂类创建,它们之间有一一对应的关系。
简单工厂模式的问题是:如果有新的需求,就需要修改工厂类里面创建产品对象实例的那个方法的实现代码,在面向对象设计一个原则就是哪里有变化,我就封装哪里。
工厂方法模式代码实现
抽象汽车类
/// <summary>
/// 汽车抽象类
/// </summary>
public abstract class Car
{
/// <summary>
/// 开始行驶
/// </summary>
public abstract void Go();
}
复制代码
具体汽车类
/// <summary>
/// ConcreteCar 具体车辆类
/// </summary>
public class ConcreteCar
{
/// <summary>
/// 红旗汽车
/// </summary>
public class HongQiCar : Car
{
public override void Go()
{
Console.WriteLine("红旗汽车开始行驶了!");
}
}
/// <summary>
/// 奥迪汽车
/// </summary>
public class AoDiCar : Car
{
public override void Go()
{
Console.WriteLine("奥迪汽车开始行驶了");
}
}
}
复制代码
抽象工厂
/// <summary>
/// 抽象工厂类
/// </summary>
public abstract class Factory
{
/// <summary>
/// 工厂方法
/// </summary>
/// <returns></returns>
public abstract Car CreateCar();
}
复制代码
具体工厂
/// <summary>
/// ConcreteFactory 具体工厂方法
/// </summary>
public class ConcreteFactory
{
/// <summary>
/// 红旗汽车工厂类
/// </summary>
public class HongQiCarFactory : Factory
{
/// <summary>
/// 负责生产红旗汽车
/// </summary>
/// <returns></returns>
public override Car CreateCar()
{
return new HongQiCar();
}
}
/// <summary>
/// 奥迪汽车工厂类
/// </summary>
public class AoDiCarFactory : Factory
{
/// <summary>
/// 负责创建奥迪汽车
/// </summary>
/// <returns></returns>
public override Car CreateCar()
{
return new AoDiCar();
}
}
}
复制代码
调用
/// <summary>
/// 测试方法
/// </summary>
public void RunTest()
{
// 初始化创建汽车的两个工厂
Factory hongQiCarFactory = new HongQiCarFactory();
Factory aoDiCarFactory = new AoDiCarFactory();
// 生产一辆红旗汽车
Car hongQi = hongQiCarFactory.CreateCar();
hongQi.Go();
//生产一辆奥迪汽车
Car aoDi = aoDiCarFactory.CreateCar();
aoDi.Go();
}
复制代码
工厂方法模式优缺点
优点:
在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
正序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
发新帖
回复
铁佛
金牌会员
这个人很懒什么都没写!
楼主热帖
R语言使用dplyr包的arrange函数对dataf ...
Visual Studio 2022 安装低版本的 .Net ...
通过cookie和localstorage实现数据持久 ...
身为一个测试工程师只会点点点?我劝您 ...
手把手教你入门Python中的Web开发框架 ...
Apifox:节省研发团队的每一分钟 ...
.net6下使用DotnetZip解压文件,中文出 ...
实现华为多屏协同--非华为电脑下载12.0 ...
[go-redis] go操作redis数据库
为什么用了大牌工具后报表开发依然头痛 ...
标签云
存储
挺好的
服务器
快速回复
返回顶部
返回列表