创建型模式:工厂模式(Factory Method)

意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

结构:
factory_method

示例:
factory_method_example

Product(Document):被工厂方法生产的产品的抽象。

class Document(ABC):

    def __init__(self, name):
        self.name = name

    @abstractmethod
    def open(self):
        """打开文档"""

    def save(self):
        print('save %s.' % self.name)

    def revert(self):
        print('revert %s.' % self.name)

ConcreteProduct(DrawingDocument、TextDocument):具体的产品类。

class DrawingDocument(Document):

    def open(self):
        print('open %s with 画图.' % self.name)


class TextDocument(Document):

    def open(self):
        print('open %s with 写字板.' % self.name)

Creator(Application):声明了工厂方法(create_document())的工厂类,可以调用工厂方法生产一个产品类。

class Application(ABC):

    def __init__(self):
        self.docs = []

    @abstractmethod
    def create_document(self, name):
        """创建文档"""

    def new_document(self, name):
        """新建并打开文档"""
        doc = self.create_document(name)
        self.docs.append(doc)
        doc.open()

ConcreteCreator(DrawingApplication、TextApplication):具体的工厂类,实现工厂方法并返回具体的ConcreteProduct对象。

class DrawingApplication(Application):

    def create_document(self, name):
        return DrawingDocument(name)


class TextApplication(Application):

    def create_document(self, name):
        return TextDocument(name)

Client:

drawing_app = DrawingApplication()

drawing_app.new_document('kobe.jpg')
drawing_app.new_document('jordan.png')
print(list(map(lambda d: d.name, drawing_app.docs)))  # ['kobe.jpg', 'jordan.png']


text_app = TextApplication()

text_app.new_document('冰与火之歌.txt')
text_app.new_document('三国演义.txt')
print(list(map(lambda d: d.name, text_app.docs)))  # ['冰与火之歌.txt', '三国演义.txt']

简单工厂:利用传入参数的不同生产所需的产品对象。

def create_document(document_type, document_name):
    """
    根据传入文档类型的不同,生产不同的文档对象
    :param document_type: 
    :param document_name: 
    :return: 
    """
    if document_type == 'DRAWING':
        return DrawingDocument(document_name)
    elif document_type == 'TEXT':
        return TextDocument(document_name)

分析:

  1. 利用简单工厂生产产品时,每当新增一个产品,就需要修改一次代码,利用工厂模式时,每新增一个产品则只需新增一个具体工厂。除此之外将工厂方法作为工厂类的静态方法,使要增加产品是则继承该工厂类。

    class Creator:
    
      @staticmethod
      def create_document(document_type, document_name):
        """
        根据传入文档类型的不同,生产不同的文档对象
        :param document_type:
        :param document_name:
        :return:
        """
        if document_type == 'DRAWING':
            return DrawingDocument(document_name)
        elif document_type == 'TEXT':
            return TextDocument(document_name)
        else:
            raise TypeError('no document')
    
    
    class SubCreator(Creator):
    
      @staticmethod
      def create_document(document_type, document_name):
        """
        根据传入文档类型的不同,生产不同的文档对象
        :param document_type:
        :param document_name:
        :return:
        """
        if document_type == 'NEW':
            return NewDocument(document_name)
        else:
            super().create_document(document_type, document_name)
  2. 工厂方法通常在Template Methods中被调用。在上面的文档例子中,NewDocument就是一个模板方法。

  3. 简单工厂:我只有一个工厂,可以造汽车,飞机。某天需要造轮船,则需要改工厂内部结构。
  4. 工厂模式:我有汽车工厂,飞机工厂,某天我要造轮船,则重新新建一个轮船工厂,而不用改之前的其他工厂。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值