工厂模式(Factory Pattern)

定义

Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
对于python这种运行时判断类型的脚本语言来说,就是一个简单工厂方法,通过工厂方法屏蔽对应的子类的创建。

UML 示例

@startuml
class NvWa
note left:女娲
abstract class AbstractHumanFactroy{
    Human createHuman(Class c)
}
note left: 抽象八卦炉
interface Human{
    +void getColor()
    +void talk()
}
note left:人类

NvWa -->AbstractHumanFactroy
NvWa -->Human
AbstractHumanFactroy ..> Human

class HumanFactory
class BlackHuman
note bottom: 黑色人种
class YellowHuman
note bottom: 黄色人种
class WhiteHuman
note bottom: 白色人种
AbstractHumanFactroy <|--HumanFactory

Human<|..BlackHuman
Human<|..YellowHuman
Human<|..WhiteHuman

@enduml

image.png

代码实现

图示中表示的 uml 类间的关系,由于 python 中没有接口概念,而 uml 中定义了作为所有 human 实现的接口,在 python 的表示的话就是各个具体的类定义。
静态语言中有接口,抽象类,而 python 中类型是在运行时检查的,所以有些区别,看起来也相对简单。
比如:代码中关于工厂类,其实在 java 中也不过是一个 factory 工厂定义一个静态方法,与此处直接用一个工厂方法表示一样。


class BlackHuman:

    def __init__(self):
        return

    def talk(self):
        print("I'm blcak human")

    def getColor(self):
        print("Black")


class WhiteHuman:

    def __init__(self):
        return

    def talk(self):
        print("I'm white human")

    def getColor(self):
        print("White")


class YellowHuman:

    def __init__(self):
        return

    def talk(self):
        print("I'm yellow human")

    def getColor(self):
        print("Yellow")


def create_human(selector):
    if selector == 'black':
        return BlackHuman()
    if selector == 'white':
        return WhiteHuman()
    if selector == 'yellow':
        return YellowHuman()

    return ValueError("selector is wrong")


if __name__ == "__main__":
    #  NvWa造人
    blackhuman = create_human('black')
    whitehuman = create_human('white')
    yellowhuman = create_human('yellow')

    blackhuman.getColor()
    whitehuman.getColor()
    yellowhuman.getColor()

知识点

  • 简单工厂使用的方法相对简单,但需要注意的是应用场景,个人理解凡是想要封闭创建某个具体对象时,都可使用简单工厂。比如连接数据库时,连接的不同的数据库,返回一个对应数据库的对象,此时通过工厂方法屏蔽掉具体创建细节;只是通过传入的参数类型来判断。
  • 再比如:根据不同的文件后缀,创建不同文件类型的对象,解析对应的文件类型。

    参考《精通 python 设计模式》第一章工厂模式之工厂方法
    参考《设计模式之禅》

下集预告:抽象工厂模式


neilliu
59 声望9 粉丝

coder is coding code snippet,coder change the world!