各位小伙伴好,今天给大家主要介绍一下简单工厂模式、工厂模式和抽象工厂模式的区别及各自的优缺点。

(本文实现语言为Python3)

【前言】

众所周知今天所讲的内容是设计模式的一类;对于设计模式这个概念,我想首先请大家问问自己:1、什么是设计模式 2、我们为什么要了解并学习设计模式?

从我上学的时候我相信大家跟我一样也接触过设计模式的课程,当时可能懵懵懂懂只是知其然,当时还会想明明可以直接写出来为什么要搞成这样的形式,我就算学会了它到底什么时候能用呢?一系列的问题...Emm算了到时候再想想(lazy)。随着实践的不断增多,现在我想可以对这些问题有个初步的回答了:

  1、在我看来,设计模式外在看是经过前人不断实践总结出的针对某些指定场景极其好用的一种代码结构设计模板;内在看其实是一种设计思想(即为什么他们会这么想,这样想较之其他方法有什么好处)。当我们真正的理解设计思想的时候,就可能会在面对问题和场景时自然而然的灵活运用到多种设计模式,而不是单一的刻板结构。

  2、在工程化的开发中,需求往往是会不断变化的,这也是让很多开发人员及其烦躁的地方,所以才会有开发与产品的亲密关系。设计模式就是为了抵御外部需求变化产生的设计模式应符合开闭原则(类、模块和函数等应该对扩展开放,对修改关闭。)一个好的设计在之后的开发中,包括发生重大需求变化的时候,往往代码只需要进行简单重构去进行适配,而不是通过打补丁的方式去堆砌,也很容易避免破窗效应,充分的发挥了灵活的扩展和适配,大大增强了维护性。

  综上所述,我们了解并学习设计模式,可以使我们的代码变得更加健壮、结构清晰,可以从容、灵活的适配需求变更(可复用、可扩展、可维护、够灵活)

【正文】

首先,这三种模式解决的问题是实例化对象的问题;那么为什么不直接实例化而用这样的工厂形式去实例化对象呢?

因为【待实例化对象太多(子类多且变动、调用频繁)或者实例化对象的过程、准备比较复杂】,直接实例化意味着每次都用重复的去执行实例化这个操作,如果有很多待实例化的操作,那么就要重复执行很多次,更不要说万一在实例化之前还要执行一堆配置项的初始化。所以用工厂模式去代替直接实例化对象是为了可复用,并且可以实现模块间的解耦。

如果是简单的实例化是没有必要引入工厂模式的,这样还会增加系统的复杂度。

简单工厂模式和抽象工厂模式都是派生于工厂模式的,属于一类;在对问题的解决上你可以理解成三种方案,解决某类问题用某种方案最好;但在复杂程度上来说算是层层递进的。我这里就按实现的简单程度升序说明。(这里我准备用实例化手机对象举例说明)

一、简单工厂模式(又叫静态工厂模式)

  顾名思义,这是对工厂模式的一种“简单”实现,也是理解起来比较简单的。它的本质是通过传入不同的参数来实现多态,达到实例化不同对象的目的。

       

    class MobileFactory:
        """ 简单工厂模式 生产手机的工厂"""

        def get_mobile(self, name):
            if name == 'huawei':
                return HuaWei()
            elif name == 'iphone':
                return Iphone()


    class MobliePhone:
        pass


    class HuaWei(MobliePhone):
        pass


    class Iphone(MobliePhone):
        pass


    hw = MobileFactory().get_mobile('huawei')
    ip = MobileFactory().get_mobile('iphone')
    print(hw)  # <__main__.HuaWei object at 0x00000000021F9160>
    print(ip)  # <__main__.Iphone object at 0x00000000022AD0F0>

二、工厂模式(又称为创建模式)

       是对简单工厂模式多了一层抽象,将实例化某一类对象具体细分给对应的工厂,而不是在一个工厂里通过依赖参数

  

    class MobileFactory:
        """ 工厂模式 生产手机的工厂"""

        def get_mobile(self):
            pass


    class HWFactory(MobileFactory):
        def get_mobile(self):
            return 'get a HW phone'


    class IphoneFactory(MobileFactory):
        def get_mobile(self):
            return 'get an iphone'


    hw, ip = HWFactory(), IphoneFactory()
    print(hw.get_mobile())  # get a HW phone
    print(ip.get_mobile())  # get an iphone

三、抽象工厂模式

  是对工厂模式又进行了一层抽象,不单单是像工厂模式只生成一类产品,而是一系列产品,并且可以像零件一样灵活配置给各工厂。

  

"""
    抽象工厂模式
    【假设】华为和苹果都生产手机和屏幕,而我家只生产屏幕
    """


    # 有屏幕和手机两款产品
    class Screen:
        def __init__(self):
            print('i am a screen')


    class Mobile:
        def __init__(self):
            print('i am a mobile')


    # 三个厂家各自的屏幕和手机
    class HWScreen(Screen):
        def __init__(self):
            print('HW screen')


    class IphoneScreen(Screen):
        def __init__(self):
            print('Iphone screen')


    class MyScreen(Screen):
        def __init__(self):
            print('My screen')


    class HWMobile(Mobile):
        def __init__(self):
            print('HW Mobile')


    class IphoneMobile(Mobile):
        def __init__(self):
            print('Iphone Mobile')


    # 生产工厂
    class Factory:
        def get_screen(self):
            pass

        def get_mobile(self):
            pass


    # 各家自己的工厂
    class HWFactory(Factory):
        def get_mobile(self):
            return HWMobile()

        def get_screen(self):
            return HWScreen()


    class IphoneFactory(Factory):
        def get_screen(self):
            return IphoneScreen()

        def get_mobile(self):
            return IphoneMobile()


    class MyFactory(Factory):
        def get_screen(self):
            return MyScreen()


    # 我要生产东西咯
    hw, ip, my = HWFactory(), IphoneFactory(), MyFactory()
    hw.get_mobile()  # HW Mobile
    hw.get_screen()  # HW screen
    ip.get_mobile()  # Iphone Mobile
    ip.get_screen()  # Iphone screen
    my.get_screen()  # My screen

【总结与说明】

  首先说明由于Python面向对象比较彻底,天然的实现了多态,所以例子看起来可能不如静态语言Java更加清晰,但是可以通过例子理解要传递表达的设计思想。

       看完上述三段代码示例后,相信大家可能有的人会豁然开朗,有的人可能只是刚刚梳理好思路。在这里我希望大家先问问自己三个模式的优缺点,并且带着对它们的疑问进行代码实践,这样才会对理解和感悟有更深刻的认识。

       一、简单工厂模式 【优点】:1、客户端创建对象时只需要记住特定的参数,而不需要记住复杂的类名,也不用关注实现的过程。(实现了封装和部分解耦)

                                                       2、创建对象不需要单独实例化,而是通过工厂类直接获取示例(实现复用)

                                     【缺点】:1、实例化对象的逻辑全部封装在一个工厂类里,每次需求变化都要单独修改工厂类(违反了开闭原则),而且出了异常可能没法正常工作。

                                                       2、不方便扩展子类

          【应用场景】:适合业务简单或者产品较少的情况

       二、工厂模式        【优点】:1、在简单工厂的基础上遵循了开闭原则,又进行了解耦,工厂类分为具体的工厂类

                                    【缺点】:1、每增加一个工厂,就要额外开发一个工厂

                                    【应用场景】:正文中符合工厂模式的情况,多由于解耦

       三、抽象工厂模式   【优点】:1、正是由于复杂的抽象关联关系使得在类的内部对一系列产品组的管理很方便

                                       【缺点】:1、扩展很费力,每次要修改很多类。

                                       【应用场景】:待创建的对象是一系列相互关联或相互依赖的产品族时

01-01 08:13