生成器模式

创建型模式

访问次数: 11

生成器模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

类图
classDiagram
    class Director {
        -builder: Builder
        +construct()
    }
    class Builder {
        <<interface>>
        +buildPartA()
        +buildPartB()
        +buildPartC()
        +getResult() Product
    }
    class ConcreteBuilder {
        -product: Product
        +buildPartA()
        +buildPartB()
        +buildPartC()
        +getResult() Product
    }
    class Product {
        -partA: String
        -partB: String
        -partC: String
        +setPartA(partA: String)
        +setPartB(partB: String)
        +setPartC(partC: String)
    }
    Director --> Builder
    Builder <|-- ConcreteBuilder
    ConcreteBuilder --> Product
源代码示例
// 产品类
class Product {
    private String partA;
    private String partB;
    private String partC;
    
    public void setPartA(String partA) {
        this.partA = partA;
    }
    
    public void setPartB(String partB) {
        this.partB = partB;
    }
    
    public void setPartC(String partC) {
        this.partC = partC;
    }
    
    @Override
    public String toString() {
        return "Product{partA='" + partA + "', partB='" + partB + "', partC='" + partC + "'}";
    }
}

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

// 具体建造者
class ConcreteBuilder implements Builder {
    private Product product = new Product();
    
    @Override
    public void buildPartA() {
        product.setPartA("Part A");
    }
    
    @Override
    public void buildPartB() {
        product.setPartB("Part B");
    }
    
    @Override
    public void buildPartC() {
        product.setPartC("Part C");
    }
    
    @Override
    public Product getResult() {
        return product;
    }
}

// 指挥者
class Director {
    private Builder builder;
    
    public Director(Builder builder) {
        this.builder = builder;
    }
    
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
# 产品类
class Product:
    def __init__(self):
        self.part_a = None
        self.part_b = None
        self.part_c = None
    
    def set_part_a(self, part_a):
        self.part_a = part_a
    
    def set_part_b(self, part_b):
        self.part_b = part_b
    
    def set_part_c(self, part_c):
        self.part_c = part_c
    
    def __str__(self):
        return f"Product{{partA='{self.part_a}', partB='{self.part_b}', partC='{self.part_c}'}}"

# 抽象建造者
from abc import ABC, abstractmethod

class Builder(ABC):
    @abstractmethod
    def build_part_a(self):
        pass
    
    @abstractmethod
    def build_part_b(self):
        pass
    
    @abstractmethod
    def build_part_c(self):
        pass
    
    @abstractmethod
    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 build_part_c(self):
        self.product.set_part_c("Part C")
    
    def get_result(self):
        return self.product

# 指挥者
class Director:
    def __init__(self, builder):
        self.builder = builder
    
    def construct(self):
        self.builder.build_part_a()
        self.builder.build_part_b()
        self.builder.build_part_c()
        return self.builder.get_result()

# 使用示例
if __name__ == "__main__":
    builder = ConcreteBuilder()
    director = Director(builder)
    product = director.construct()
    print(product)
应用场景
当需要创建复杂对象,且对象的构建过程需要分步骤进行时。应用场景包括: 1)构建一个复杂的SQL查询,需要逐步添加SELECT、FROM、WHERE、ORDER BY等子句 2)创建复杂的邮件对象,需要设置发件人、收件人、主题、正文、附件等部分 3)构建HTTP请求对象,需要设置URL、请求头、请求体、认证信息、超时设置等参数 4)创建复杂的配置文件对象,需要设置数据库连接、缓存配置、日志配置、安全配置等多个部分 5)构建游戏角色对象,需要设置基础属性、技能、装备、背包、任务等多个复杂组件
精选场景详解 —— SQL 构建:分步组装复杂查询
问题背景

动态报表需要按条件拼接 SELECT、JOIN、WHERE、ORDER BY。用字符串拼接易出错、难复用,且无法保证「必填子句」与构造顺序。

模式如何解决
选用生成器(Builder)模式:SqlQueryBuilder 提供 select、from、where、orderBy、build 等步骤方法;Director(或业务服务)按场景编排调用顺序,最终 build() 得到不可变的 SqlQuery。 好处: 1)把复杂构造过程拆成清晰步骤; 2)同一套步骤可构建不同查询变体; 3)可在 build 时校验完整性(例如必须有 FROM)。 与工厂的区别:工厂关注「创建哪个类」,Builder 关注「同一个复杂对象如何一步步填满」。
场景模型(角色映射)

将模式中的抽象角色映射到该业务领域的具体类:

classDiagram
    class SqlQueryBuilder {
        <<interface>>
        +select(cols: String) SqlQueryBuilder
        +from(table: String) SqlQueryBuilder
        +where(cond: String) SqlQueryBuilder
        +orderBy(expr: String) SqlQueryBuilder
        +build() SqlQuery
    }
    class DefaultSqlQueryBuilder {
        -query: SqlQuery
        +select(cols: String) SqlQueryBuilder
        +from(table: String) SqlQueryBuilder
        +where(cond: String) SqlQueryBuilder
        +orderBy(expr: String) SqlQueryBuilder
        +build() SqlQuery
    }
    class SqlQuery {
        -selectClause: String
        -fromClause: String
        -whereClause: String
        -orderByClause: String
        +toSql() String
    }
    class ReportQueryDirector {
        -builder: SqlQueryBuilder
        +buildSalesReport() SqlQuery
        +buildUserReport() SqlQuery
    }
    SqlQueryBuilder <|.. DefaultSqlQueryBuilder
    DefaultSqlQueryBuilder --> SqlQuery
    ReportQueryDirector --> SqlQueryBuilder