当前位置:首页>文章>设计模式>建造者模式详解 | Python实现与应用场景对比工厂模式

建造者模式详解 | Python实现与应用场景对比工厂模式

建造者模式详解

1️⃣ 概念

定义: 将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。

特征: 用户只需指定建造的类型就可以得到他们,建造过程及细节不需要知道。

类型: 创建型

2️⃣ 适用场景

  • 如果一个对象有非常复杂的内部结构(例如有很多属性)
  • 想把复杂对象的创建和使用分离

3️⃣ 优点

  • 封装性好,创建和使用分离
  • 扩展性好,建造类之间独立,一定程度上解耦

4️⃣ 缺点

  • 产生多余的Builder对象
  • 产品内部发生变化,建造者都要修改,成本较大

5️⃣ 建造者模式与工厂模式的区别

  • 关注点不同: 建造者模式注重于方法的调用顺序,而工厂模式注重于创建产品
  • 创建对象的粒度不同: 建造者模式可以创建一些复杂的产品,由各种复杂的部件组成;工厂模式创建出来的对象都是一个样子的
  • 细节层面不同: 工厂模式关注的是主要把这个对象创建出来就OK了,建造者模式创建产品的时候还需要知道创建出的这个产品是由哪些部件组成的

6️⃣ 建造者模式 Python实现

我们以攒电脑为例来演示建造者模式的实现。

① 声明抽象的Builder类

from abc import ABC, abstractmethod

class Builder(ABC):
    @abstractmethod
    def build_cpu(self, cpu):
        pass

    @abstractmethod
    def build_main_board(self, main_board):
        pass

    @abstractmethod
    def build_hard_disk(self, hard_disk):
        pass

    @abstractmethod
    def build_display_card(self, display_card):
        pass

    @abstractmethod
    def build_power(self, power):
        pass

    @abstractmethod
    def build_memory(self, memory):
        pass

    @abstractmethod
    def create_computer(self):
        pass

② 声明电脑实体类Computer

class Computer:
    def __init__(self):
        self.cpu = None
        self.main_board = None
        self.hard_disk = None
        self.display_card = None
        self.power = None
        self.memory = None

    def get_cpu(self):
        return self.cpu

    def set_cpu(self, cpu):
        self.cpu = cpu

    def get_main_board(self):
        return self.main_board

    def set_main_board(self, main_board):
        self.main_board = main_board

    def get_hard_disk(self):
        return self.hard_disk

    def set_hard_disk(self, hard_disk):
        self.hard_disk = hard_disk

    def get_display_card(self):
        return self.display_card

    def set_display_card(self, display_card):
        self.display_card = display_card

    def get_power(self):
        return self.power

    def set_power(self, power):
        self.power = power

    def get_memory(self):
        return self.memory

    def set_memory(self, memory):
        self.memory = memory

    def __str__(self):
        return f"Computer(cpu='{self.cpu}', main_board='{self.main_board}', " \
               f"hard_disk='{self.hard_disk}', display_card='{self.display_card}', " \
               f"power='{self.power}', memory='{self.memory}')"

③ 声明ActualBuilder类来继承Builder

class ActualBuilder(Builder):
    def __init__(self):
        self.computer = Computer()

    def build_cpu(self, cpu):
        self.computer.set_cpu(cpu)

    def build_main_board(self, main_board):
        self.computer.set_main_board(main_board)

    def build_hard_disk(self, hard_disk):
        self.computer.set_hard_disk(hard_disk)

    def build_display_card(self, display_card):
        self.computer.set_display_card(display_card)

    def build_power(self, power):
        self.computer.set_power(power)

    def build_memory(self, memory):
        self.computer.set_memory(memory)

    def create_computer(self):
        return self.computer

④ 创建DirectorBoss类

class DirectorBoss:
    def __init__(self):
        self.builder = None

    def set_builder(self, builder):
        self.builder = builder

    def create_computer(self, cpu, main_board, hard_disk, display_card, power, memory):
        self.builder.build_cpu(cpu)
        self.builder.build_main_board(main_board)
        self.builder.build_hard_disk(hard_disk)
        self.builder.build_display_card(display_card)
        self.builder.build_power(power)
        self.builder.build_memory(memory)
        return self.builder.create_computer()

⑤ 创建测试代码

if __name__ == "__main__":
    builder = ActualBuilder()
    director_boss = DirectorBoss()
    director_boss.set_builder(builder)
    computer = director_boss.create_computer("酷睿I7", "华硕主板", "希捷2T硬盘", 
                                            "英伟达显卡", "长城电源", "威刚内存条8G")
    print(computer)

7️⃣ 建造者 Python实现 演进

以上的代码实例存在一些缺陷,首先DirectorBoss并不是必需的,另外create_computer方法的入参较多很容易出错,所以我们对建造者的实例进行演进。

① 创建优化后的Computer类

class Computer:
    def __init__(self, computer_builder):
        self.cpu = computer_builder.cpu
        self.main_board = computer_builder.main_board
        self.hard_disk = computer_builder.hard_disk
        self.display_card = computer_builder.display_card
        self.power = computer_builder.power
        self.memory = computer_builder.memory

    def __str__(self):
        return f"Computer(cpu='{self.cpu}', main_board='{self.main_board}', " \
               f"hard_disk='{self.hard_disk}', display_card='{self.display_card}', " \
               f"power='{self.power}', memory='{self.memory}')"

    class ComputerBuilder:
        def __init__(self):
            self.cpu = None
            self.main_board = None
            self.hard_disk = None
            self.display_card = None
            self.power = None
            self.memory = None

        def build_cpu(self, cpu):
            self.cpu = cpu
            return self

        def build_main_board(self, main_board):
            self.main_board = main_board
            return self

        def build_hard_disk(self, hard_disk):
            self.hard_disk = hard_disk
            return self

        def build_display_card(self, display_card):
            self.display_card = display_card
            return self

        def build_power(self, power):
            self.power = power
            return self

        def build_memory(self, memory):
            self.memory = memory
            return self

        def build(self):
            return Computer(self)

② 创建优化后的测试代码

if __name__ == "__main__":
    computer = Computer.ComputerBuilder() \
        .build_cpu("酷睿I7") \
        .build_main_board("华硕主板") \
        .build()
    print(computer)

    # Python中类似Google Guava的ImmutableSet的用法
    immutable_set = frozenset(['a', 'b'])
    print(immutable_set)

8️⃣ 建造者模式的实际应用

① 在Python标准库中的应用

Python的字符串拼接虽然不像Java的StringBuilder,但可以使用类似的模式:

class StringBuilder:
    def __init__(self):
        self._strings = []

    def append(self, obj):
        self._strings.append(str(obj))
        return self

    def append_string(self, string):
        self._strings.append(string)
        return self

    def append_char(self, char):
        self._strings.append(char)
        return self

    def append_bool(self, boolean):
        self._strings.append(str(boolean))
        return self

    def __str__(self):
        return ''.join(self._strings)

    def build(self):
        return ''.join(self._strings)

# 使用示例
result = StringBuilder() \
    .append("Hello") \
    .append_string(" ") \
    .append("World") \
    .append_bool(True) \
    .build()
print(result)  # HelloWorldTrue

② 建造者模式在Flask中的应用

Flask框架中的应用构建也使用了类似的模式:

from flask import Flask

class FlaskAppBuilder:
    def __init__(self):
        self.app = Flask(__name__)
        self.config = {}
        self.blueprints = []

    def set_config(self, key, value):
        self.config[key] = value
        return self

    def add_blueprint(self, blueprint):
        self.blueprints.append(blueprint)
        return self

    def set_debug(self, debug):
        self.config['DEBUG'] = debug
        return self

    def set_secret_key(self, secret_key):
        self.config['SECRET_KEY'] = secret_key
        return self

    def build(self):
        # 应用配置
        for key, value in self.config.items():
            self.app.config[key] = value

        # 注册蓝图
        for blueprint in self.blueprints:
            self.app.register_blueprint(blueprint)

        return self.app

# 使用示例
# app = FlaskAppBuilder() \
#     .set_debug(True) \
#     .set_secret_key('your-secret-key') \
#     .set_config('DATABASE_URL', 'sqlite:///app.db') \
#     .add_blueprint(some_blueprint) \
#     .build()

③ 建造者模式在Django中的应用

Django的QuerySet也采用了类似的链式调用模式:

# Django ORM的链式调用示例(概念展示)
class QuerySetBuilder:
    def __init__(self, model):
        self.model = model
        self.conditions = []
        self.order_fields = []
        self.limit_num = None

    def filter(self, **kwargs):
        self.conditions.append(('filter', kwargs))
        return self

    def exclude(self, **kwargs):
        self.conditions.append(('exclude', kwargs))
        return self

    def order_by(self, *fields):
        self.order_fields.extend(fields)
        return self

    def limit(self, num):
        self.limit_num = num
        return self

    def build(self):
        # 这里会构建实际的查询
        query_info = {
            'model': self.model,
            'conditions': self.conditions,
            'order_fields': self.order_fields,
            'limit': self.limit_num
        }
        return query_info

# 使用示例
# query = QuerySetBuilder(User) \
#     .filter(age__gte=18) \
#     .exclude(is_active=False) \
#     .order_by('-created_at') \
#     .limit(10) \
#     .build()
设计模式

设计模式:工厂模式详解(Python版)

2025-8-29 10:23:46

工具配置

Void AI编辑器完全指南:免费开源Cursor替代品安装配置教程 | AI编程工具

2025-7-29 14:59:38

搜索