当前位置: 首页 > news >正文

Python设计模式:工厂模式

1. 什么是工厂模式?

工厂模式是一种创建对象的设计模式,它提供了一种创建对象的接口,但不暴露对象创建的具体逻辑。工厂模式的核心思想是将对象的创建与使用分离,从而提高代码的灵活性和可维护性。

1.1 工厂模式的类型

1.1.1 简单工厂模式(Simple Factory Pattern)

简单工厂模式通过一个工厂类来创建不同类型的对象。工厂类根据传入的参数决定创建哪种类型的对象。这种模式并不属于 GoF 设计模式中的 23 种设计模式,但在实际应用中非常常见。

# 产品接口
class Product:
    def operation(self):
        pass

# 具体产品类
class ConcreteProductA(Product):
    def operation(self):
        return "Result of ConcreteProductA"

class ConcreteProductB(Product):
    def operation(self):
        return "Result of ConcreteProductB"

# 工厂类
class SimpleFactory:
    @staticmethod
    def create_product(product_type):
        if product_type == "A":
            return ConcreteProductA()
        elif product_type == "B":
            return ConcreteProductB()
        else:
            raise ValueError("Unknown product type")

# 客户端代码
if __name__ == "__main__":
    factory = SimpleFactory()
    
    product_a = factory.create_product("A")
    print(product_a.operation())  # 输出: Result of ConcreteProductA

    product_b = factory.create_product("B")
    print(product_b.operation())  # 输出: Result of ConcreteProductB
  1. 产品接口:定义了一个产品接口 Product,具体产品类 ConcreteProductAConcreteProductB 实现了该接口。
  2. 工厂类SimpleFactory 类提供了一个静态方法 create_product,根据传入的参数创建不同类型的产品。
  3. 客户端代码:在客户端代码中,使用工厂类创建产品对象,而不需要直接依赖具体的产品类。

1.1.2 工厂方法模式(Factory Method Pattern)

工厂方法模式定义一个创建对象的接口,但由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。这种模式允许用户在不修改现有代码的情况下引入新产品。

# 产品接口
class Product:
    def operation(self):
        pass

# 具体产品类
class ConcreteProductA(Product):
    def operation(self):
        return "Result of ConcreteProductA"

class ConcreteProductB(Product):
    def operation(self):
        return "Result of ConcreteProductB"

# 工厂接口
class Factory:
    def create_product(self):
        pass

# 具体工厂类
class ConcreteFactoryA(Factory):
    def create_product(self):
        return ConcreteProductA()

class ConcreteFactoryB(Factory):
    def create_product(self):
        return ConcreteProductB()

# 客户端代码
if __name__ == "__main__":
    factory_a = ConcreteFactoryA()
    product_a = factory_a.create_product()
    print(product_a.operation())  # 输出: Result of ConcreteProductA

    factory_b = ConcreteFactoryB()
    product_b = factory_b.create_product()
    print(product_b.operation())  # 输出: Result of ConcreteProductB
  1. 产品接口:定义了一个产品接口 Product,具体产品类 ConcreteProductAConcreteProductB 实现了该接口。
  2. 工厂接口:定义了一个工厂接口 Factory,包含一个创建产品的方法 create_product
  3. 具体工厂类ConcreteFactoryAConcreteFactoryB 实现了工厂接口,负责创建具体产品。
  4. 客户端代码:在客户端代码中,使用具体工厂类创建产品对象,而不需要直接依赖具体的产品类。

工厂方法模式的一个重要优点是它允许用户在不修改现有代码的情况下引入新产品。这是通过以下方式实现的:

  1. 扩展工厂类:用户可以创建新的工厂类,继承自工厂接口,并实现 create_product 方法,以创建新的产品类型。

  2. 扩展产品类:用户可以创建新的产品类,继承自产品接口,并实现其方法。

  3. 使用多态:客户端代码可以使用工厂接口来创建产品,而不需要知道具体的产品类。这使得在引入新产品时,客户端代码不需要进行任何修改。

假设我们要引入一个新的产品 ConcreteProductC 和一个新的工厂 ConcreteFactoryC

# 新的具体产品类
class ConcreteProductC(Product):
    def operation(self):
        return "Result of ConcreteProductC"

# 新的具体工厂类
class ConcreteFactoryC(Factory):
    def create_product(self):
        return ConcreteProductC()

# 客户端代码
if __name__ == "__main__":
    factory_a = ConcreteFactoryA()
    product_a = factory_a.create_product()
    print(product_a.operation())  # 输出: Result of ConcreteProductA

    factory_b = ConcreteFactoryB()
    product_b = factory_b.create_product()
    print(product_b.operation())  # 输出: Result of ConcreteProductB

    # 使用新的工厂和产品
    factory_c = ConcreteFactoryC()
    product_c = factory_c.create_product()
    print(product_c.operation())  # 输出: Result of ConcreteProductC
  1. 新的具体产品类ConcreteProductC 实现了 Product 接口,提供了自己的 operation 方法。
  2. 新的具体工厂类ConcreteFactoryC 实现了 Factory 接口,负责创建 ConcreteProductC 实例。
  3. 客户端代码:在客户端代码中,创建了新的工厂 ConcreteFactoryC,并使用它来创建新的产品 ConcreteProductC。客户端代码无需修改,依然使用工厂接口来创建产品。

1.1.3 抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式通常用于需要创建多个相关对象的场景。

# 产品接口
class ProductA:
    def operation_a(self):
        pass

class ProductB:
    def operation_b(self):
        pass

# 具体产品类
class ConcreteProductA1(ProductA):
    def operation_a(self):
        return "Result of ConcreteProductA1"

class ConcreteProductA2(ProductA):
    def operation_a(self):
        return "Result of ConcreteProductA2"

class ConcreteProductB1(ProductB):
    def operation_b(self):
        return "Result of ConcreteProductB1"

class ConcreteProductB2(ProductB):
    def operation_b(self):
        return "Result of ConcreteProductB2"

# 抽象工厂接口
class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass

# 具体工厂类
class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA1()

    def create_product_b(self):
        return ConcreteProductB1()

class ConcreteFactory2(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA2()

    def create_product_b(self):
        return ConcreteProductB2()

# 客户端代码
if __name__ == "__main__":
    factory1 = ConcreteFactory1()
    product_a1 = factory1.create_product_a()
    product_b1 = factory1.create_product_b()
    print(product_a1.operation_a())  # 输出: Result of ConcreteProductA1
    print(product_b1.operation_b())  # 输出: Result of ConcreteProductB1

    factory2 = ConcreteFactory2()
    product_a2 = factory2.create_product_a()
    product_b2 = factory2.create_product_b()
    print(product_a2.operation_a())  # 输出: Result of ConcreteProductA2
    print(product_b2.operation_b())  # 输出: Result of ConcreteProductB2
  1. 产品接口:定义了两个产品接口 ProductAProductB,具体产品类实现了这些接口。
  2. 抽象工厂接口:定义了一个抽象工厂接口 AbstractFactory,包含创建产品的方法。
  3. 具体工厂类ConcreteFactory1ConcreteFactory2 实现了抽象工厂接口,负责创建一系列相关的产品。
  4. 客户端代码:在客户端代码中,使用具体工厂类创建产品对象,而不需要直接依赖具体的产品类。

1.2 工厂模式的优点

  • 解耦:客户端代码与具体的产品类解耦,客户端只需要依赖于工厂接口。
  • 灵活性:可以在不修改客户端代码的情况下引入新的产品类。
  • 易于扩展:可以通过添加新的工厂类和产品类来扩展系统。

1.3 工厂模式的应用场景

  • 当一个类不知道它所必须创建的对象的类时。
  • 当一个类希望通过子类来指定它所创建的对象时。
  • 当需要将对象的创建与使用分离时。

2. 示例 1:工厂模式在图形绘制应用中的应用

# 图形接口
class Shape:
    def draw(self):
        pass


# 具体图形类
class Circle(Shape):
    def __init__(self, color):
        self.color = color

    def draw(self):
        return f"Drawing a {self.color} Circle"


class Rectangle(Shape):
    def __init__(self, color):
        self.color = color

    def draw(self):
        return f"Drawing a {self.color} Rectangle"


class Triangle(Shape):
    def __init__(self, color):
        self.color = color

    def draw(self):
        return f"Drawing a {self.color} Triangle"


class Square(Shape):
    def __init__(self, color):
        self.color = color

    def draw(self):
        return f"Drawing a {self.color} Square"


# 工厂类
class ShapeFactory:
    @staticmethod
    def create_shape(shape_type, color):
        if shape_type == "Circle":
            return Circle(color)
        elif shape_type == "Rectangle":
            return Rectangle(color)
        elif shape_type == "Triangle":
            return Triangle(color)
        elif shape_type == "Square":
            return Square(color)
        else:
            raise ValueError("Unknown shape type")


# 图形管理器
class ShapeManager:
    def __init__(self):
        self.shapes = []

    def add_shape(self, shape):
        self.shapes.append(shape)

    def draw_all(self):
        for shape in self.shapes:
            print(shape.draw())


# 客户端代码
if __name__ == "__main__":
    shape_manager = ShapeManager()

    # 直接定义形状类型和颜色
    shapes_to_create = [
        ("Circle", "Red"),
        ("Rectangle", "Blue"),
        ("Triangle", "Green"),
        ("Square", "Yellow")
    ]

    for shape_type, color in shapes_to_create:
        shape = ShapeFactory.create_shape(shape_type, color)
        shape_manager.add_shape(shape)

    # 绘制所有图形
    shape_manager.draw_all()
Drawing a Red Circle
Drawing a Blue Rectangle
Drawing a Green Triangle
Drawing a Yellow Square
  1. 图形接口:定义了一个图形接口 Shape,所有具体图形类(如 CircleRectangleTriangleSquare)都实现了该接口,并提供了 draw 方法。

  2. 具体图形类:每个具体图形类都有一个构造函数,接受颜色参数,并实现了 draw 方法,返回绘制该图形的描述。

  3. 工厂类ShapeFactory 类提供了一个静态方法 create_shape,根据传入的形状类型和颜色创建不同类型的图形对象。这样,客户端代码只需调用工厂方法,而不需要直接依赖具体的图形类。

  4. 图形管理器ShapeManager 类用于管理所有创建的图形对象。它可以添加图形并绘制所有图形。

  5. 客户端代码:在客户端代码中,直接定义了一个形状和颜色的列表,使用工厂类创建相应的图形对象,并将它们添加到图形管理器中。最后,调用 draw_all 方法绘制所有图形。

http://www.dtcms.com/a/122770.html

相关文章:

  • 凯斯西储大学CWRU数据集变体
  • python中的数据模型-pydantic浅讲
  • 02_SQL分库分表及Java实现
  • 【重构谷粒商城12】npm快速入门
  • Python第八章:数据可视化——Json数据
  • Android 开发中compileSdkVersion 和 targetSdkVersion
  • Vue2下载二进制文件
  • 【动手学深度学习】LeNet:卷积神经网络的开山之作
  • 【面试】封装、继承、多态的具象示例 模板编程的理解与应用场景 链表适用的场景
  • 【vue】slot插槽:灵活内容分发的艺术
  • R语言——散点图
  • 第九章:可靠通信_《凤凰架构:构建可靠的大型分布式系统》
  • WHAT - React useId vs uuid
  • Pascal VOC 2012 数据集格式与文件结构
  • 前端性能优化的全方位方案【待进一步结合项目】
  • Redis 持久化+性能管理+缓存
  • XSS靶场闯关小游戏
  • 10A 大电流 DCDC 降流芯片 WD5030
  • 2025年AI开发学习路线
  • springboot集成大华人脸机
  • js实现跨域下载,展示下载进度以及自定义下载名称功能
  • Docker新型容器镜像构建技术,如何正确高效的编写Dockerfile
  • 前端三件套—CSS入门
  • 13_pandas可视化_seaborn
  • 青少年编程与数学 02-016 Python数据结构与算法 10课题、搜索
  • Webstorm 使用搜不到node_modules下的JS内容 TS项目按Ctrl无法跳转到函数实现
  • leetcode刷题日记——验证回文串
  • 算法比赛中常用的数学知识
  • C# Winform 入门(15)之制作二维码和拼接(QR)
  • miniconda安装R语言图文教程(详细步骤)