当前位置: 首页 > article >正文

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

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


http://www.kler.cn/a/413447.html

相关文章:

  • eduSRC挖洞思路
  • Linux ACL 权限详解与多场景实践
  • 预处理指令
  • DB2数据库
  • 用两个栈实现队列 剑指offer
  • Linux服务器生成SSH 密钥对与 GitLab 仓库进行交互
  • AI助力PPT创作:从手动到智能,打造高效演示
  • 比特币libsecp256k1中safegcd算法形式化验证完成
  • Java基于SSM框架的校园综合服务小程序【附源码、文档】
  • thinkphp中对请求封装
  • matlab模糊fis文件制作
  • 《Vue零基础入门教程》第八课:模板语法
  • docker compose的安装和使用
  • el-row el-col显示失效问题修复
  • CTF之密码学(栅栏加密)
  • IntelliJ+SpringBoot项目实战(十六)--在SpringBoot中整合SpringSecurity和JWT(下A)
  • Jenkins流水线 Allure JUnit5 自动化测试
  • vue3项目搭建-4-正式启动项目,git管理
  • 如何寻找适合的HTTP代理IP资源?
  • 13 —— 开发环境调错-source map
  • 本地部署 WireGuard 无需公网 IP 实现异地组网
  • Redis中如何使用lua脚本-即redis与lua的相互调用
  • coqui-ai TTS 初步使用
  • React的基本知识:事件监听器、Props和State的区分、改变state的方法、使用回调函数改变state、使用三元运算符改变state
  • 命令行版 postman 之 post 小工具
  • TDengine 签约深圳综合粒子,赋能粒子研究新突破