【设计模式】【创建型模式(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 小时前
C++设计模式之组合模式中适用缓存机制提高遍历与查找速度
c++·设计模式·组合模式
夏旭泽1 小时前
设计模式-工厂模式
设计模式·简单工厂模式
渊渟岳2 小时前
设计模式--原型模式及其编程思想
设计模式
春风十里不如你95272 小时前
【设计模式】【行为型模式(Behavioral Patterns)】之观察者模式(Observer Pattern)
观察者模式·设计模式
春风十里不如你95275 小时前
【设计模式】【结构型模式(Structural Patterns)】之代理模式(Proxy Pattern)
设计模式·代理模式
请你打开电视看看9 小时前
观察者模式
java·观察者模式·设计模式
Mr.朱鹏9 小时前
设计模式之策略模式-工作实战总结与实现
java·spring·设计模式·kafka·maven·策略模式·springbbot
春风十里不如你95279 小时前
【设计模式】【结构型模式(Structural Patterns)】之组合模式(Composite Pattern)
设计模式·组合模式
捕鲸叉10 小时前
C++设计模式之组合模式实践原则
c++·设计模式·组合模式