美文网首页
设计模式(python实现)--工厂模式(Factory)

设计模式(python实现)--工厂模式(Factory)

作者: 远行_2a22 | 来源:发表于2019-12-29 16:17 被阅读0次

动机

在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?

模式定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。

要点总结

  • Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
  • Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
  • Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

UML

image.png

红色框中表示的是稳定的部分。


例子-文件分割:

原始的分割器只支持文件分割功能

class MainForm(object):
    def __init__(self):
        pass

    def click_button(self):
        splitter = FileSplitter()
        splitter.split()


class FileSplitter(object):
    def split(self):
        print('FileSplitter split')


if __name__ == '__main__':
    main_form = MainForm()
    main_form.click_button()

但是后续需要支持二进制分割、图片分割等。
MainForm依赖FileSplitter。根据依赖导致原则, MainForm必须依赖抽象,不能依赖具体。

使用工厂方法

# -*- coding:utf-8 -*-

class MainForm(object):
    def __init__(self, factory_obj):
        self.factory_obj = factory_obj

    def click_button(self):
        splitter = self.factory_obj.create_splitter()
        splitter.split()

class SplitterBase(object):
    def split(self):
        pass

class FileSplitter(SplitterBase):
    def split(self):
        print('FileSplitter split')


class BinarySplitter(SplitterBase):
    def split(self):
        print('BinarySplitter split')


class SplitterFactoryBase(object):
    def create_splitter(self):
        pass


class FileSplitterFactory(object):
    def create_splitter(self):
        return FileSplitter()


class BinarySplitterFactory(object):
    def create_splitter(self):
        return BinarySplitter()


if __name__ == '__main__':
    main_form = MainForm(FileSplitterFactory())
    main_form.click_button()

这样MainForm就不依赖具体类,当随着需求变化添加新的分割器时,只需要添加对应的实现类,和工厂类即可。

对照UML分析

对照UML, 该例子中,
SplitterFactoryBase对应AbstractFactory
SplitterBase对应AbstractProduct
FileSplitterBinarySplitter 对应ConcreteProduct
FileSplitterFactoryBinarySplitterFactory 对应ConcreteFactory

问题

  • 问题1:虽然MainForm不依赖具体类,但是调用MainForm的地方,肯定需要创建具体类,不就仍然依赖了具体类了吗?
    答:我们无法消除依赖,只能把依赖赶到其他地方。因此必须清楚哪里需要稳定,这里MainForm稳定后,无论需求如何变化,不需要再修改MainForm类,而只需要修改调用它的地方,比如这里的main()。因此把依赖都放在一起,这样改变的时候只需要修改这里即可,从而提高代码的稳定性。

  • 问题2:为什么不直接传入具体的分割器,反而如此麻烦的要创建这么多的工厂类,如下:


class MainForm(object):
    def __init__(self, splitter):
        self.splitter = splitter

    def click_button(self):
        self.splitter.split()

class SplitterBase(object):
    def split(self):
        pass

class FileSplitter(SplitterBase):
    def split(self):
        print('FileSplitter split')

class BinarySplitter(SplitterBase):
    def split(self):
        print('BinarySplitter split')


if __name__ == '__main__':
    main_form = MainForm(FileSplitter())
    main_form.click_button()

例子-造车

使用工厂模式实现造不同类型的汽车

# -*- coding:utf-8 -*-

class CarBase(object):
    def speed_up(self):
        pass

# 奔驰汽车
class BenzCar(CarBase):
    def speed_up(self):
        print('BenzCar speed_up')


# 宝马汽车
class BmwCar(CarBase):
    def speed_up(self):
        print('BenzCar speed_up')


class CarFactoryBase(object):
    def create_car(self):
        pass


class BenzFactory(CarFactoryBase):
    def create_car(self):
        return BenzCar()


class BmwFactory(CarFactoryBase):
    def create_car(self):
        return BmwCar()

if __name__ == '__main__':
    car = BenzFactory().create_car()
    car.speed_up()

相关文章

网友评论

      本文标题:设计模式(python实现)--工厂模式(Factory)

      本文链接:https://www.haomeiwen.com/subject/nuyyoctx.html