Clean code: Python Builder模式

Feilong's Blog / 2024-09-14 / 原文

在 Python 中,Builder 模式(构建者模式)是一种创建型设计模式,通常用于构建复杂对象。它将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的对象。虽然 Python 语言由于其动态特性,不像 Java、C# 等语言那样强制使用 Builder 模式,但它在某些情况下仍然非常有用,尤其是当你需要构建具有多个可选参数的复杂对象时。

以下是一个简单的 Builder 模式在 Python 中的例子:

示例:构建一辆汽车的 Builder

我们将通过 Builder 模式来构建一辆汽车(Car),汽车有一些可选的特性,比如引擎类型、颜色、座椅类型等。

class Car:
    def __init__(self):
        self.engine = None
        self.wheels = None
        self.color = None
        self.seats = None

    def __str__(self):
        return f"Car with {self.engine} engine, {self.wheels} wheels, {self.color} color, {self.seats} seats."


class CarBuilder:
    def __init__(self):
        self.car = Car()

    def set_engine(self, engine_type):
        self.car.engine = engine_type
        return self  # 返回 builder 自身以便支持链式调用

    def set_wheels(self, wheels_count):
        self.car.wheels = wheels_count
        return self

    def set_color(self, color):
        self.car.color = color
        return self

    def set_seats(self, seats_count):
        self.car.seats = seats_count
        return self

    def build(self):
        return self.car


# 客户端代码
builder = CarBuilder()
car = (builder.set_engine("V8")
       .set_wheels(4)
       .set_color("Red")
       .set_seats(2)
       .build())

print(car)  # 输出: Car with V8 engine, 4 wheels, Red color, 2 seats.

解释

  1. Car 类:代表最终构建的对象。它有多个属性,如引擎、车轮、颜色和座椅等。
  2. CarBuilder 类:这是构建者类,负责设置不同的属性并最终返回构建好的 Car 对象。每个设置方法都会返回自身,以支持链式调用。
  3. 链式调用CarBuilder 的每个设置方法返回 self,这样用户可以在一次调用中设置多个属性,而不需要每次重新调用 CarBuilder 的实例。
  4. build() 方法:当所有需要的属性都设置完成后,调用 build() 方法返回最终构建好的对象。

示例:更复杂的 Director 角色

在更复杂的场景中,可以使用 Director 类,它负责调用 Builder 的构建步骤,决定如何去构建对象。

class CarDirector:
    def __init__(self, builder):
        self._builder = builder

    def construct_sports_car(self):
        return (self._builder
                .set_engine("V8")
                .set_wheels(4)
                .set_color("Red")
                .set_seats(2)
                .build())

    def construct_family_car(self):
        return (self._builder
                .set_engine("V6")
                .set_wheels(4)
                .set_color("Blue")
                .set_seats(5)
                .build())


# 客户端代码
builder = CarBuilder()
director = CarDirector(builder)

sports_car = director.construct_sports_car()
family_car = director.construct_family_car()

print(sports_car)  # 输出: Car with V8 engine, 4 wheels, Red color, 2 seats.
print(family_car)  # 输出: Car with V6 engine, 4 wheels, Blue color, 5 seats.

解释

  • Director 类:它负责控制构建的流程。它通过调用 Builder 类中的方法来构建不同类型的对象(如运动型汽车、家庭汽车等)。Director 不需要知道具体如何构建对象,只需要知道哪些步骤需要调用。
  • Builder 和 Director 分离:通过将构建的过程与具体的对象表示分离,我们可以灵活地更改构建逻辑,而不影响客户端代码。同时,Director 提供了不同的构建方案,如构建运动型汽车和家庭汽车。

什么时候使用 Builder 模式?

  • 当一个对象有许多可选参数或复杂的构建步骤时,使用 Builder 模式可以避免构造函数中的大量参数。
  • 当你希望代码更具可读性时,链式调用的方式能让构建过程更直观。
  • 如果同一个构建过程可以生成不同的产品,那么 Builder 模式非常适用。

总结

在 Python 中使用 Builder 模式虽然不像在 Java 或 C++ 中那样普遍,但它在处理复杂对象构建时仍然非常有用。通过使用 Builder 模式,你可以更加优雅、灵活地创建复杂对象,尤其是当对象具有多种可选配置时。