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

来源:互联网 发布:手机淘宝差评怎么删掉 编辑:程序博客网 时间:2024/06/06 04:19

意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。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