工厂方法模式

引入-简单工厂模式的不足

  • 简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,加入必要的处理逻辑,违背了开闭原则
  • 在简单工厂模式中,所有的产品都是由同一个工厂创建,工厂类职责较重,业务逻辑复杂,具体类与工厂类之间的耦合度较高,严重影响了系统的扩展性灵活性

模式定义

  • 工厂方法模式又称为工厂模式虚拟构造器模式多态工厂模式,它属于创建型模式
  • 在工厂模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责创建具体的产品对象,这样做可以将产品类的实例化操作延迟到工厂子类中完成

模式结构与分析

模式结构图
在这里插入图片描述
模式角色如下

  • 抽象产品Product
    抽象产品是定义产品的接口,是产品对象的共同父类或接口
  • 具体产品ConcreteProduct
    具体产品实现了抽象产品接口,某种具体类型的产品由专门的具体工厂创建,它们之间是一一对应的关系
  • 抽象工厂Factory
    在抽象工厂类中声明了工厂方法,用语返回一个产品。所有创建产品对象的具体工厂都必须实现这一接口
  • 具体工厂ConcreteFactory
    具体工厂是抽象工厂的子类,它实现了抽象工厂中定义的工厂方法,由应用程序调用,返回一个具体的产品对象的实例

模式实例与解析

  • 实例说明
    某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等,且用户可以根据要求动态选择日志记录方式,现使用工厂方法模式设计该系统
  • 实例类图
    在这里插入图片描述
  • 代码实现

抽象产品类Log

class Log(ABC):
    '''抽象产品类'''
    @abstractclassmethod
    def writeLog(self):
        pass
class FileLog(Log)

具体产品类FileLog

class FileLog(Log):
    '''具体产品类'''
    def writeLog(self):
        print('从文件写入日志记录')

具体产品类DataBaseLog

class DataBaseLog(Log):
    '''具体产品类'''
    def writeLog(self):
        print('从数据库中写入日志记录')

抽象工厂类LogFactory

class LogFactory(ABC):
    '''抽象工厂类'''
    @abstractclassmethod
    def createLog(self):
        pass

具体工厂类FileLogFactory

class FileLogFactory(LogFactory):
    '''具体工厂类'''
    def createLog(self):
        print('创建文件日志')

具体工厂类DataBaseLogFactory

class DataBaseLogFactory(LogFactory):
    '''具体工厂类'''
    def createLog(self):
        print('创建数据库日志')
        return DataBaseLog()

测试代码

factory = DataBaseLogFactory()
log = factory.createLog()
log.writeLog()

结果
在这里插入图片描述

模式优缺点

优点

  • 在工厂方法模式中,用户只需要关心所需产品对应的工厂,而不需要关心产品创建的细节,甚至不需要知道具体产品类的类名
  • 基于工厂角色和产品角色的多态性设计使得工厂方法模式可以自主确定创建何种产品对象
  • 在系统中加入一个新产品时,只要加入具体的产品类和具体的工厂即可,系统扩展性好,符合开闭原则

缺点

  • 添加新产品时,系统中类的个数成对增加(具体产品和具体工厂),一定程度上增加了系统的复杂度,给系统带来了一些额外的开销
  • 抽象层使得系统的理解难度增加

模式适用环境

  • 一个类不知道它所需要的对象的类
    由于在工厂方法模式中客户端只需知道创建产品对象的工厂类名,而不知道具体产品对象的类名
  • 一个类通过其子类来指定创建哪个对象
  • 将创建对象的任务交给多个工厂子类中的某一个

模式应用

1.Java集合框架中的java.util.Collection接口的**iterator()**工厂方法使得具体的java集合类可以通过实现该方法返回一个Iterator迭代器对象
2.Java消息服务JMS的实现广泛使用工厂方法模式
3.JDBC中也大量使用工厂方法模式,例如在创建连接对象Connection、语句对象Statement和结果集对象ResultSet时都使用工厂方法

模式扩展

1.使用多个工厂方法
在抽象工厂类中定义多个多个工厂方法,让具体工厂角色实现这些不同的工厂方法,完成不同的业务功能,满足不同的产品对象的功能
2.产品对象的重复使用

  • 在实际情况中工厂方法所做的事可以非常复杂,一个常用的复杂逻辑就是重复使用产品对象
  • 工厂对象将已经创建过的产品保存到一个集合(数组,List)中,然后根据客户对产品的要求,从集合中查询。如果集合中没有满足需求的产品对象,则创建一个新的满足要求的产品对象并加入到集合中,返回给客户端,这是享元模式的设计思想

3.多态性的丧失和模式的退化
当只有一个具体工厂,具体工厂中创建所有的产品对象,并且将工厂方法设计为静态方法时,工厂方法模式就退化为简单工厂模式

实验

问题描述
现需要设计一个程序来读取多种不同类型的图片格式,针对每一种图片格式设计一个图片读取器(ImageReader),如GIF图片读取器(GifReader)用于读取GIF格式的图片,JPEG图片读取器(JpgReader)用于读取JPEG格式的图片。
UML图
在这里插入图片描述
设计代码

  • 抽象产品类ImgReader
class ImgReader(metaclass=ABCMeta):
    '''抽象图片读取类''' 
    @abstractclassmethod
    def read(self):
        '''抽象读取方法'''
        pass
  • 具体产品类JpgReader和GifReader
class JpgReader(ImgReader):
    '''jpg格式照片'''
    def read(self):
        print('读取jpg格式的照片')
class GifReader(ImgReader):
    '''gif格式的照片'''
    def read(self):
        print('读取gif格式的照片')
  • 抽象工厂类ReaderFactory
class ReaderFactory(metaclass=ABCMeta):
    '''抽象工厂'''
    @abstractclassmethod
    def create_reader(self):
        '''抽象制造读取器'''
        pass
  • 具体工厂类JpgReaderFactory和GifReaderFactory
class JpgReaderFactory(ReaderFactory):
    '''jpg格式图片读取器工厂'''

    def create_reader(self):
        return JpgReader()

class GifReaderFactory(ReaderFactory):
    '''gif格式图片读取器工厂'''

    def create_reader(self):
        return GifReader()

小结

  • 工厂方法模式又称工厂模式,属于类创建型模式
  • 工厂方法包含4个角色:抽象产品、具体产品、抽象工厂、具体工厂
  • 工厂方法是简单工厂模式的进一步抽象和推广
  • 工厂方法的优点
  • 工厂方法的适用情况
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂方法模式是一种常见的创建型设计模式,它定义了一个用于创建对象的接口,但是由子类决定要实例化的类是哪一个。在工厂方法模式中,创建对象的过程被分离出来,使得这个过程可以被子类定制化,从而提高了代码的可扩展性和可维护性。 工厂方法模式的核心思想是将对象的创建和使用分离开来,客户端只需要知道所需对象的类型,而无需关心对象的创建过程。具体来说,工厂方法模式包含以下几个角色: 1. 抽象工厂(Abstract Factory):定义了工厂方法的接口,用于创建产品对象。 2. 具体工厂(Concrete Factory):实现抽象工厂接口,根据具体需求创建具体产品对象。 3. 抽象产品(Abstract Product):定义了产品的接口,用于描述产品的属性和行为。 4. 具体产品(Concrete Product):实现抽象产品接口,提供具体的实现。 使用工厂方法模式可以将客户端代码和具体产品的实现代码分离开来,使得代码更加灵活和可扩展。工厂方法模式在实际应用中也有很多场景,例如: 1. 当一个类不知道它所必须创建的对象的类的时候。 2. 当一个类希望由它的子类来指定所创建的对象的时候。 3. 当类将创建对象的职责委托给多个帮助子类中的某个特定子类,并且希望能够在运行时切换这些子类中的哪一个时。 总之,工厂方法模式是一种非常实用的设计模式,可以提高代码的可维护性和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值