Python实现设计模式--02.工厂模式(Factory Pattern)

设计模式》涉及到创建类的几种模式,共同的也是最根本的原则就是:不要new对象!!!既然如此,告诉我你最先想到的是如何得到对象呢?没错,“你不让我new,那你给我个get对象的工具吧,别的我不管”。这就是工厂模式,工厂模式是一种简单又实用的模式,在各大框架到处可见,比如Java世界大名鼎鼎的spring,其本身就是一个大工厂。

工厂模式中,工厂的作用是解耦调用者和被调用者的关系,工厂模式又分为工厂方法模式和简单工厂模式。我们先说工厂方法模式,下面举个现实的栗子。

比如说一个鞋厂,生产皮鞋和球鞋,安利公司打电话来说给我一批皮鞋,恒大足球队打电话说来给我一批球鞋,鞋厂很开心的按时交付了。我们用代码来模拟这个场景,鞋厂就是抽象工厂,其下两个车间--皮鞋车间和球鞋车间--是具体的工厂,皮鞋和球鞋都是产品,安利和恒大是客户端。下面是实现代码:

# 鞋,基类(抽象产品类)
class Shoe:
    def walk(self):
        pass


# 皮鞋(具体产品)
class LeatherShoe(Shoe):
    def walk(self):
        print("优雅的皮鞋,去拉客户中")


# 球鞋(具体产品)
class SoccerShoe(Shoe):
    def walk(self):
        print("愤怒的球鞋,正在蹂躏草坪")


# 鞋厂,基类(抽象工厂)
class ShoeFactory:
    def make_shoe(self):
        pass


# 皮鞋车间(具体工厂)
class LeatherShoeFactory(ShoeFactory):
    def make_shoe(self):
        return LeatherShoe()


# 球鞋车间(具体工厂)
class SoccerShoeFactory(ShoeFactory):
    def make_shoe(self):
        return SoccerShoe()


# 安利打电话要鞋
def anli_call():
    factory = LeatherShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe()
        shoe.walk()


# 恒大打电话要鞋
def hengda_call():
    factory = SoccerShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe()
        shoe.walk()


if __name__ == '__main__':
    anli_call()
    hengda_call()

这里模拟安利和恒大分别下单购了3双鞋,运行结果如下:

优雅的皮鞋,去拉客户中
优雅的皮鞋,去拉客户中
优雅的皮鞋,去拉客户中
愤怒的球鞋,正在蹂躏草坪
愤怒的球鞋,正在蹂躏草坪
愤怒的球鞋,正在蹂躏草坪
上面例子中的每个具体工厂都只生产一种产品,假设该鞋厂很牛逼,一个车间什么鞋都能生产。我们去掉两个子工厂,把父工厂改为这样:
# 鞋厂,基类(抽象工厂)
class ShoeFactory:
    def make_shoe(self, name):
        if name == "LeatherShoe":
            return LeatherShoe()
        elif name == "SoccerShoe":
            return SoccerShoe()
        else:
            return None
客户方法要改为如下:
# 安利打电话要鞋
def anli_call():
    factory = ShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe("LeatherShoe")
        shoe.walk()


# 恒大打电话要鞋
def hengda_call():
    factory = ShoeFactory()
    for i in range(3):
        shoe = factory.make_shoe("SoccerShoe")
        shoe.walk()
运行结果和上面一下,这种被称为简单工厂模式。简单工厂模式相对工厂方法模式代码复杂度有所降低,但是每次增加产品,就要修改工厂类,扩展性差。

读者应该会纳闷了,这什么玩意,整这么复杂,我几行代码循环new几个对象完事儿。是的,例子中这种简单的实体对象是不需要工厂模式的,用它来举例是因为它很能体现“工厂”的概念。说实话本人真正在项目中没有用到工厂模式,都只是在框架里见到它的出现,比如spring对bean对管理、json序列化生成单例类等。感觉只有在写框架的时候才需要它,业务代码多是行为类,以策略模式居多,不过话说到此,是不是可以用工厂模式管理行为类呢?回头我尝试一下。


下面是我的一点感受:
工厂与产品之间是一种弱联系,将上面例子中的球鞋车间改为生产皮鞋,完全不会有任何问题,所以工厂模式需要良好的命名约定。再加上python是弱语言类型,又没有抽象的概念,很难约束子类,这样在设计工厂的时候务必保持类名清晰,使调用者一眼就知道能得到什么产品。

你可能感兴趣的:(设计模式-python)