美文网首页
设计模式(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