【设计模式】【创建型模式(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. 可扩展性:增加新的建造者类时,无需修改现有代码,符合开闭原则。

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

相关推荐
程序员沉梦听雨32 分钟前
原型模式详解
设计模式·原型模式
coderzpw1 小时前
谁该处理我的请假?——责任链模式
设计模式·责任链模式
云徒川3 小时前
【设计模式】组合模式
设计模式·组合模式
01空间4 小时前
设计模式简述(九)命令模式
设计模式
01空间6 小时前
设计模式简述(十一)装饰器模式
设计模式
辰辰大美女呀6 小时前
C 语言高级编程指南:回调函数与设计模式
c语言·开发语言·设计模式
01空间6 小时前
设计模式简述(六)代理模式
设计模式
cijiancao8 小时前
23种设计模式中的观察者模式
观察者模式·设计模式
前期后期10 小时前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
java·前端·设计模式
01空间11 小时前
设计模式简述(八)中介者模式
设计模式