【设计模式】【创建型模式(Creational Patterns)】之建造者模式(Builder Pattern)

建造者模式(Builder Pattern) 是一种创建型设计模式,它允许你逐步构造复杂对象,而不必使用一个庞大的构造函数。建造者模式的主要目的是将对象的构建过程与其表示分离,从而使得相同的构建过程可以创建不同的表示。

主要角色
  1. Builder(抽象建造者):定义创建一个产品对象的各个部件的接口。
  2. ConcreteBuilder(具体建造者):实现 Builder 接口,构建和装配各个部件,最终构造出产品对象。
  3. Director(导演类):负责调用具体的建造者来构建产品的各个部件。
  4. Product(产品类):表示被构造的复杂对象,包含多个部件。

2. UML 类图及解释

UML 类图
复制代码
+----------------+                +---------------------+
|   Director     |                | ConcreteBuilder     |
|----------------|                |---------------------|
| - builder: Builder              | - product: Product  |
|                                |                     |
| + construct(): void            | + buildPartA(): void|
| + setBuilder(builder: Builder):| + buildPartB(): void|
|   void                            | + getResult(): Product |
+----------------+                +---------------------+
        |                                  ^
        |                                  |
        |                                  |
        v                                  |
+----------------+                         |
|   Builder      |                         |
|----------------|                         |
| - product: Product                       |
|                                +---------+
| + buildPartA(): void                    |
| + buildPartB(): void                    |
| + getResult(): Product                  |
+----------------+                        |
                                           
                                           
+----------------+                         |
|   Product      |                         |
|----------------|                         |
| - partA: string                           |
| - partB: string                           |
|                                +---------+
| + setPartA(partA: string): void          |
| + setPartB(partB: string): void          |
+----------------+                         |
类图解释
  • Director:负责调用具体的建造者来构建产品的各个部件。它不依赖于具体的产品类,而是依赖于抽象建造者。
  • Builder:定义了一个创建产品对象的接口,但不具体实现。具体实现由具体的建造者类完成。
  • ConcreteBuilder:实现了 Builder 接口,负责构建和装配各个部件,最终构造出产品对象。
  • Product:表示被构造的复杂对象,包含多个部件。具体的建造者类会逐步构建这个对象。

3. 代码案例及逻辑详解

Java 代码案例
复制代码
// 产品类
class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "Product [partA=" + partA + ", partB=" + partB + "]";
    }
}

// 抽象建造者
interface Builder {
    void buildPartA();
    void buildPartB();
    Product getResult();
}

// 具体建造者
class ConcreteBuilder implements Builder {
    private Product product;

    public ConcreteBuilder() {
        this.product = new Product();
    }

    @Override
    public void buildPartA() {
        product.setPartA("Part A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("Part B");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

// 导演类
class Director {
    private Builder builder;

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Director director = new Director();
        ConcreteBuilder builder = new ConcreteBuilder();

        director.setBuilder(builder);
        director.construct();

        Product product = builder.getResult();
        System.out.println(product);
    }
}
C++ 代码案例
复制代码
#include <iostream>
#include <string>

// 产品类
class Product {
public:
    std::string partA;
    std::string partB;

    void setPartA(const std::string& partA) {
        this->partA = partA;
    }

    void setPartB(const std::string& partB) {
        this->partB = partB;
    }

    friend std::ostream& operator<<(std::ostream& os, const Product& p) {
        return os << "Product [partA=" << p.partA << ", partB=" << p.partB << "]";
    }
};

// 抽象建造者
class Builder {
public:
    virtual void buildPartA() = 0;
    virtual void buildPartB() = 0;
    virtual Product* getResult() = 0;
};

// 具体建造者
class ConcreteBuilder : public Builder {
private:
    Product* product;

public:
    ConcreteBuilder() {
        product = new Product();
    }

    ~ConcreteBuilder() {
        delete product;
    }

    void buildPartA() override {
        product->setPartA("Part A");
    }

    void buildPartB() override {
        product->setPartB("Part B");
    }

    Product* getResult() override {
        return product;
    }
};

// 导演类
class Director {
private:
    Builder* builder;

public:
    void setBuilder(Builder* builder) {
        this->builder = builder;
    }

    void construct() {
        builder->buildPartA();
        builder->buildPartB();
    }
};

// 客户端代码
int main() {
    Director director;
    ConcreteBuilder builder;

    director.setBuilder(&builder);
    director.construct();

    Product* product = builder.getResult();
    std::cout << *product << std::endl;

    return 0;
}
Python 代码案例
复制代码
# 产品类
class Product:
    def __init__(self):
        self.partA = None
        self.partB = None

    def set_part_a(self, partA):
        self.partA = partA

    def set_part_b(self, partB):
        self.partB = partB

    def __str__(self):
        return f"Product [partA={self.partA}, partB={self.partB}]"

# 抽象建造者
class Builder:
    def build_part_a(self):
        pass

    def build_part_b(self):
        pass

    def get_result(self):
        pass

# 具体建造者
class ConcreteBuilder(Builder):
    def __init__(self):
        self.product = Product()

    def build_part_a(self):
        self.product.set_part_a("Part A")

    def build_part_b(self):
        self.product.set_part_b("Part B")

    def get_result(self):
        return self.product

# 导演类
class Director:
    def __init__(self):
        self.builder = None

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

    def construct(self):
        self.builder.build_part_a()
        self.builder.build_part_b()

# 客户端代码
if __name__ == "__main__":
    director = Director()
    builder = ConcreteBuilder()

    director.set_builder(builder)
    director.construct()

    product = builder.get_result()
    print(product)
Go 代码案例
复制代码
package main

import "fmt"

// 产品类
type Product struct {
    PartA string
    PartB string
}

func (p *Product) SetPartA(partA string) {
    p.PartA = partA
}

func (p *Product) SetPartB(partB string) {
    p.PartB = partB
}

func (p *Product) String() string {
    return fmt.Sprintf("Product [partA=%s, partB=%s]", p.PartA, p.PartB)
}

// 抽象建造者
type Builder interface {
    BuildPartA()
    BuildPartB()
    GetResult() *Product
}

// 具体建造者
type ConcreteBuilder struct {
    product *Product
}

func NewConcreteBuilder() *ConcreteBuilder {
    return &ConcreteBuilder{product: &Product{}}
}

func (b *ConcreteBuilder) BuildPartA() {
    b.product.SetPartA("Part A")
}

func (b *ConcreteBuilder) BuildPartB() {
    b.product.SetPartB("Part B")
}

func (b *ConcreteBuilder) GetResult() *Product {
    return b.product
}

// 导演类
type Director struct {
    builder Builder
}

func (d *Director) SetBuilder(builder Builder) {
    d.builder = builder
}

func (d *Director) Construct() {
    d.builder.BuildPartA()
    d.builder.BuildPartB()
}

// 客户端代码
func main() {
    director := &Director{}
    builder := NewConcreteBuilder()

    director.SetBuilder(builder)
    director.Construct()

    product := builder.GetResult()
    fmt.Println(product)
}

4. 总结

建造者模式 是一种非常有用的创建型设计模式,尤其适用于构建复杂的对象。通过将对象的构建过程与其表示分离,建造者模式使得相同的构建过程可以创建不同的表示。这种模式的主要优点包括:

  1. 封装性:将复杂的构建过程封装在建造者类中,客户端无需知道具体的构建细节。
  2. 灵活性:可以通过不同的建造者类创建不同类型的产品对象,增加了系统的灵活性。
  3. 可扩展性:增加新的建造者类时,无需修改现有代码,符合开闭原则。

然而,建造者模式也有一些缺点,例如代码量会增加,且在简单对象的构建中可能显得过于复杂。因此,选择是否使用建造者模式应根据具体的需求和场景来决定。

相关推荐
麓殇⊙1 小时前
设计模式--桥接模式详解
设计模式·桥接模式
学习机器不会机器学习2 小时前
深入浅出JavaScript常见设计模式:从原理到实战(1)
开发语言·javascript·设计模式
ApeAssistant6 小时前
Spring + 设计模式 (二十) 行为型 - 中介者模式
spring·设计模式
ApeAssistant6 小时前
Spring + 设计模式 (十九) 行为型 - 访问者模式
spring·设计模式
〆、风神6 小时前
从零实现分布式WebSocket组件:设计模式深度实践指南
分布式·websocket·设计模式
前端大白话6 小时前
Vue2和Vue3语法糖差异大揭秘:一文读懂,开发不纠结!
javascript·vue.js·设计模式
前端大白话6 小时前
JavaScript中`Symbol.for()`和`Symbol()`的区别,在创建全局唯一的`Symbol`值时如何选择使用?
前端·javascript·设计模式
CHQIUU7 小时前
Java 设计模式心法之第25篇 - 中介者 (Mediator) - 用“中央协调”降低对象间耦合度
java·设计模式·中介者模式
Pasregret8 小时前
备忘录模式:实现对象状态撤销与恢复的设计模式
运维·服务器·设计模式
碎梦归途10 小时前
23种设计模式-行为型模式之备忘录模式(Java版本)
java·jvm·设计模式·软考·备忘录模式·软件设计师·行为型模式