likes
comments
collection
share

Python实现工厂模式和抽象工厂模式

作者站长头像
站长
· 阅读数 4

设计模式在软件工程中用于解决常见的软件设计问题。工厂模式和抽象工厂模式是创建型设计模式中最常用的模式之一,它们用于创建对象,而不必暴露创建对象的逻辑。

本文中将详细介绍如何在Python中实现这两种模式。

工厂模式

工厂模式定义了一个创建对象的接口,但让子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。

步骤 1: 定义产品接口

首先定义一个产品接口,所有的产品类都应该实现这个接口。

class Product:
    def use(self):
        pass

步骤 2: 创建具体产品类

根据产品接口创建具体的产品类。

class ConcreteProductA(Product):
    def use(self):
        return "Inside ConcreteProductA's use() method."

class ConcreteProductB(Product):
    def use(self):
        return "Inside ConcreteProductB's use() method."

步骤 3: 定义工厂接口

定义一个工厂接口,提供一个创建对象的方法。

class Creator:
    def factory_method(self):
        pass

步骤 4: 实现具体工厂

实现具体的工厂类,用于创建具体产品的实例。

class ConcreteCreatorA(Creator):
    def factory_method(self):
        return ConcreteProductA()

class ConcreteCreatorB(Creator):
    def factory_method(self):
        return ConcreteProductB()

步骤 5: 使用工厂

最后,根据需要使用具体的工厂创建产品实例。

creator = ConcreteCreatorA()
product = creator.factory_method()
print(product.use())  # 输出: Inside ConcreteProductA's use() method.

抽象工厂模式

抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。

步骤 1: 定义抽象产品

定义多个抽象产品,表示一系列相关或依赖的对象。

class AbstractProductA:
    def use(self):
        pass

class AbstractProductB:
    def interact(self, productA):
        pass

步骤 2: 创建具体产品类

根据抽象产品创建具体产品类。

class ProductA1(AbstractProductA):
    def use(self):
        return "The result of product A1."

class ProductB1(AbstractProductB):
    def interact(self, productA):
        return f"The result of B1 interacting with ({productA.use()})"

class ProductA2(AbstractProductA):
    def use(self):
        return "The result of product A2."

class ProductB2(AbstractProductB):
    def interact(self, productA):
        return f"The result of B2 interacting with ({productA.use()})"

步骤 3: 定义抽象工厂

定义抽象工厂接口,包含创建一系列相关或依赖对象的方法。

class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass

步骤 4: 实现具体工厂

实现具体的工厂类,每个工厂负责创建一系列产品。

class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ProductA1()

    def create_product_b(self):
        return ProductB1()

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

    def create_product_b(self):
        return ProductB2()

步骤 5: 使用抽象工厂

最后,使用具体的工厂创建一系列相关或依赖的对象。

factory1 = ConcreteFactory1()
productA1 = factory1.create_product_a()
productB1 = factory1.create

_product_b()
print(productB1.interact(productA1))  # 输出: The result of B1 interacting with (The result of product A1.)

factory2 = ConcreteFactory2()
productA2 = factory2.create_product_a()
productB2 = factory2.create_product_b()
print(productB2.interact(productA2))  # 输出: The result of B2 interacting with (The result of product A2.)

对比

下表对比了工厂模式和抽象工厂模式的主要特点、优点、缺点以及适用场景,帮助更好地理解它们之间的差异:

特性工厂模式抽象工厂模式
目的提供一个创建对象的接口,将对象的实例化延迟到子类提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
实现复杂度较低较高
适用场景当创建对象的逻辑比较简单时;当系统需要增加产品的种类时,而不是产品等级结构时当需要创建的对象是一系列相关或相互依赖的家族时;当系统中的产品族需要扩展,而不需要增加新的产品等级结构时
产品结构通常用于创建单一产品用于创建产品族
如何扩展添加新的具体工厂类添加新的产品族需要扩展抽象工厂接口和所有具体工厂类,增加新的产品等级结构相对容易
客户端如何使用客户端需要知道它们使用的具体工厂类客户端通过抽象接口操作实例,不需要知道具体工厂类
优点简化了对象的创建过程,降低了客户端与具体产品之间的耦合度可以确保同一产品族中的对象是兼容的;隔离了具体类的生成,使得客户端和具体类的实现解耦
缺点当产品种类非常多时,会增加代码维护的复杂度当产品族中需要增加新的产品时,所有的工厂类都需要进行修改,违反了开闭原则;使得系统中类的个数成倍增加,增加了系统的复杂度和理解难度

可以看出,工厂模式适合那些产品种类较少而产品等级结构较多的情况,而抽象工厂模式则适合需要操作多个产品族中产品的情况。选择哪一种模式主要取决于你的具体需求以及你希望如何组织系统中的对象创建逻辑。

结尾

工厂模式和抽象工厂模式在Python中的实现展示了如何封装对象的创建过程,使得系统更加模块化,降低了组件间的耦合度。通过使用这些模式,可以在增加新的产品或产品族时,使得代码更加灵活和可扩展。理解并掌握这些设计模式,对于设计和实现复杂系统具有重要意义。