文章目录

  • 工厂模式定义:
  • 它的优点:
  • 可以有如下三种实现方式
  • 1.简单工厂模式
  • 2.工厂方法模式
  • 3.抽象工厂模式
  • 总结


工厂模式定义:

在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类。通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法。
客户端使用某些参数调用此方法,之后,工厂会据此创建所需类型的对象,然后将它们返回给客户端。

它的优点:

  • 松耦合,对象的创建独立于类的实现
  • 客户端无需了解创建对象的类,只需知道需要传递的接口,方法和参数就能够创建所需要的对象
  • 很容易扩展工厂添加其他类型对象的创建,而使用者只需要改变参数就可以了

可以有如下三种实现方式

1.简单工厂模式

先建立一个可乐抽象类,再建立两个子类可口可乐和百事可乐实现类,再建立一个工厂类来获取需要的类

示例代码如下:

from abc import ABCMeta, abstractmethod

"""
建立一个可乐的抽象类,百事可乐和可口可乐继承这个抽象类
ABCMeta是python的一个元类,用于在Python程序中创建抽象基类,抽象基类中声明的抽象方法,使用abstractmethod装饰器装饰。
"""
class Coke(metaclass=ABCMeta):

    @abstractmethod
    def drink(self):
        pass

class Kekou(Coke):
    def drink(self):
        print('喝可口可乐')


class Baishi(Coke):
    def drink(self):
        print('喝百事可乐')

"""
建立快餐店类,也就是所说的工厂类,让它生产可乐。
当用户需要可乐时,只需要告诉快餐店做一份什么品牌的可乐,告诉快餐店可乐的名字,然后快餐店使用make_coke方法做可乐,返回了你所需要的对象
拿到可口可乐的对象,就可以调用自己实现的方法了。
"""
class Fast_food_restaurant:
    def make_coke(self, name):
        # eval(类名)返回的是一个class类型的对象
        return eval(name)()

kfc = Fast_food_restaurant()
coke = kfc.make_coke('Kekou')
coke.drink()

2.工厂方法模式

以上功能的实现得益于eval函数的使用,如果不用这个函数该如何实现呢?

可以将原来的工厂类变成抽象类,不同类型的可乐通过不同的子类生产,也就是工厂方法模式定义了一个创建对象的接口,
但具体创建哪个类的对象由子类来决定,这种方式的逻辑判断相当于交给了客户端,这样如果有新可乐产品出现的话,只需要再写一个子类继承工厂抽象类。

示例代码如下:

from abc import ABCMeta, abstractmethod

class Coke(metaclass=ABCMeta):
    # 这里是一个抽象的产品类
    @abstractmethod
    def drink(self):
        pass

class Kekou(Coke):
    # 具体产品类
    def drink(self):
        print('喝可口可乐')

class Baishi(Coke):
    # 具体产品类
    def drink(self):
        print('喝百事可乐')

"""
这里变成抽象工厂类:
"""

class Fast_food_restaurant(metaclass=ABCMeta):

    @abstractmethod
    def make_coke(self):
        # eval(类名)返回的是一个class类型的对象
        # return eval(name)()
        # 如果这里不用eval这个方法,该如何实现呢,这里工厂类也是一个抽象类,再创建不同可乐厂商的实现类即可
        pass

"""
具体工厂类-可口可乐
"""

class kekou_produce(Fast_food_restaurant):
    def make_coke(self):
        return Kekou()

"""
具体工厂类-百事可乐
"""

class baishi_produce(Fast_food_restaurant):
    def make_coke(self):
        return Baishi()

kfc = kekou_produce()
coke = kfc.make_coke()
coke.drink()

3.抽象工厂模式

抽象工厂模式的主要目的是提供一个接口来创建一系列相关对象而无需指定具体的类。这个模式与与工厂方法模式的区别在于,它的一个方法子类,可以创建一系列的对象。

如果可乐又分为冰可乐和普通可乐,于是我们的抽象产品类变为了两个,一个是冰可乐,一个是普通可乐,
具体产品类有百事冰可乐、可口可乐冰可乐,普通百事,普通可口可乐。
抽象工厂类有生产冰可乐和生产普通可乐的抽象方法,具体工厂类有百事工厂,可口可乐工厂

from abc import ABCMeta, abstractmethod

class Ice_Coke(metaclass=ABCMeta):
    # 这里是一个抽象的产品类
    @abstractmethod
    def drink(self):
        pass

class Oridinary_Coke(metaclass=ABCMeta):
    # 这里是一个抽象的产品类
    @abstractmethod
    def drink(self):
        pass

class kekou_Ice(Ice_Coke):
    # 具体产品类
    def drink(self):
        print('喝可口冰可乐')

class kekou_Ori(Oridinary_Coke):
    # 具体产品类
    def drink(self):
        print('喝可口普通可乐')

class Baishi_Ice(Ice_Coke):
    # 具体产品类
    def drink(self):
        print('喝百事冰可乐')

class Baishi_Ori(Oridinary_Coke):
    # 具体产品类
    def drink(self):
        print('喝百事普通可乐')

class Fast_food_restaurant(metaclass=ABCMeta):

    @abstractmethod
    def make_ice_coke(self):
        pass

    @abstractmethod
    def make_ori_coke(self):
        pass

"""
具体工厂类-可口可乐
"""

class kekou_produce(Fast_food_restaurant):
    def make_ice_coke(self):
        return kekou_Ice()

    def make_ori_coke(self):
        return kekou_Ori()

"""
具体工厂类-百事可乐
"""

class baishi_produce(Fast_food_restaurant):
    def make_ori_coke(self):
        return Oridinary_Coke()

    def make_ice_coke(self):
        return Ice_Coke()


kfc = kekou_produce()
coke = kfc.make_ice_coke()
coke.drink()
coke = kfc.make_ori_coke()
coke.drink()

总结

工厂模式在实际的应用场景举例:

假如有一个消息通知的功能,需要实现根据不同的消息内容发送到邮件、微信等渠道。我们就可以利用工厂模式来进行解耦,以后如果新增了短信等其他通知方式,就可以轻松应对,对原有代码侵入较低,可以方便的进行扩展功能。