.NET 设计模式—工厂方法模式(Factory Method Pattern)

简介

工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。这种模式使得对象的创建延迟到子类,从而实现了对扩展开放、对修改关闭的原则。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。工厂方法模式是一种类创建型模式。

优点

  • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,就正是因为所有的具体工厂类都具有同一抽象父类。
  • 使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。

缺点

  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。

应用场景

  • 灵活性和可扩展性:当需要一个框架能够灵活地、可扩展地处理多种产品时,工厂方法模式是一个合适的选择。例如,在设计一个连接邮件服务器的框架时,如果有多种网络协议可供选择,如POP3、IMAP、HTTP,可以将这些连接方法作为产品类,通过工厂方法根据不同的条件选择不同的连接方式,从而实现完美的扩展性。
  • 异构项目交互:工厂方法模式也适用于异构项目交互。例如,通过WebService与一个非Java项目交互时,可以将从WSDL中产生的对象视为产品,由一个具体的工厂类进行管理,减少与外围系统的耦合。
  • 测试驱动开发:在测试驱动开发的框架下,工厂方法模式可以用来虚拟出与被测试类有关联关系的类,避免这些类之间的耦合。例如,测试一个类A时,可以使用工厂方法模式来创建与类A关联的类B的虚拟实例。
  • 多种专卖店的情况:在实际生活中,如果有多个专卖店,每家专卖店销售的电脑品牌不同,可以使用工厂方法模式来处理这种情况。每个专卖店(超类)可以有多个子类,每个子类决定提供什么型号的电脑。这样,当需要购买电脑时,可以通过相应的工厂类来获取特定品牌和型号的电脑。

实现

通过一个案例来演示工厂方法模式:使用工厂方法模式设计一个程序来读取各种不同类型的文件,针对每一种文件都设计一个文件读取器,如office文件读取器用于读取office格式的文件、PDF文件读取器用于读取PDF格式的文件。需充分考虑系统的灵活性和可扩展性。

  • 定义抽象产品类(文件接口):
/// <summary>
/// 文件接口类
/// </summary>
public interface IFile
{
    void GetFiles();
}
  • 具体产品实现类:
 /// <summary>
 /// 产品类:Office文件
 /// </summary>
 public class OfficeFile : IFile
 {
     public void GetFiles()
     {
         Console.WriteLine("获取Office类型文件!");
     }
 }

/// <summary>
/// 产品类:PDF文件
/// </summary>
public class PDFFile : IFile
{
    public void GetFiles()
    {
        Console.WriteLine("获取PDF文件!");
    }
}
  • 定义抽象工厂类:
/// <summary>
/// 文件抽象工厂类
/// </summary>
public interface IFileFactory
{
    IFile GetFileList();
}
  • 具体产品工厂类:
 /// <summary>
 /// 产品工厂:Office文件
 /// </summary>
 public class OfficeFactory : IFileFactory
 {
     public IFile GetFileList()
     {
         return new OfficeFile();
     }
 }

/// <summary>
/// 产品工厂:PDF文件
/// </summary>
internal class PDFFactory : IFileFactory
{
    public IFile GetFileList()
    {
        return new PDFFile();
    }
}
  • 上层应用调用:
{
    //获取Office文件
    IFileFactory fileFactory = new OfficeFactory();
    IFile file = fileFactory.GetFileList();
    file.GetFiles();
}

{
    //获取PDF文件
    IFileFactory fileFactory = new PDFFactory();
    IFile file = fileFactory.GetFileList();
    file.GetFiles();
}

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉量*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值