设计模式解密:建造者模式的终极指南(PHP/Go双实现)
一、什么是建造者模式?
建造者模式(Builder Pattern) 是一种创建型设计模式,用于分步骤构建复杂对象。其核心思想是将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表现形式。建造者模式特别适用于具有多个可选参数或配置项的对象。
核心角色:
产品(Product):最终要构建的复杂对象
建造者接口(Builder):定义构建步骤的抽象方法
具体建造者(Concrete Builder):实现构建逻辑
指挥者(Director):控制构建流程(可选)
二、适用场景
✅ 需要创建包含多个组件的复杂对象
✅ 对象的构建过程需要分步骤控制
✅ 需要创建不同表现形式的同类对象
✅ 避免构造函数参数过多(如超过4个参数)
三、PHP实现方案
1. 基础实现(带方法链)
class Computer {
private $cpu;
private $ram;
private $storage;
public function __construct() {
$this->cpu = "Default CPU";
$this->ram = "8GB";
$this->storage = "256GB SSD";
}
public function setCpu(string $cpu): void {
$this->cpu = $cpu;
}
public function setRam(string $ram): void {
$this->ram = $ram;
}
public function setStorage(string $storage): void {
$this->storage = $storage;
}
public function getSpecs(): string {
return "CPU: {$this->cpu}, RAM: {$this->ram}, Storage: {$this->storage}";
}
}
class ComputerBuilder {
private $computer;
public function __construct() {
$this->computer = new Computer();
}
public function setCpu(string $cpu): self {
$this->computer->setCpu($cpu);
return $this;
}
public function setRam(string $ram): self {
$this->computer->setRam($ram);
return $this;
}
public function setStorage(string $storage): self {
$this->computer->setStorage($storage);
return $this;
}
public function build(): Computer {
return $this->computer;
}
}
// 使用示例
$builder = new ComputerBuilder();
$computer = $builder->setCpu("Intel i7")
->setRam("32GB DDR4")
->setStorage("1TB NVMe SSD")
->build();
echo $computer->getSpecs(); // 输出:CPU: Intel i7, RAM: 32GB DDR4, Storage: 1TB NVMe SSD
2. 进阶实现(带指挥者)
interface Builder {
public function reset(): void;
public function setCpu(string $cpu): void;
public function setRam(string $ram): void;
public function setStorage(string $storage): void;
}
class GamingComputerBuilder implements Builder {
private $computer;
public function reset(): void {
$this->computer = new Computer();
}
public function setCpu(string $cpu): void {
$this->computer->setCpu($cpu);
}
public function setRam(string $ram): void {
$this->computer->setRam($ram);
}
public function setStorage(string $storage): void {
$this->computer->setStorage($storage);
}
public function getProduct(): Computer {
return $this->computer;
}
}
class Director {
public function buildHighEndComputer(Builder $builder): Computer {
$builder->reset();
$builder->setCpu("AMD Ryzen 9");
$builder->setRam("64GB DDR5");
$builder->setStorage("2TB PCIe 4.0 SSD");
return $builder->getProduct();
}
}
// 使用示例
$director = new Director();
$builder = new GamingComputerBuilder();
$computer = $director->buildHighEndComputer($builder);
echo $computer->getSpecs(); // 输出:CPU: AMD Ryzen 9, RAM: 64GB DDR5, Storage: 2TB PCIe 4.0 SSD
四、Go实现方案
1. 基础实现(函数选项模式)
package main
import "fmt"
type Computer struct {
CPU string
RAM string
Storage string
}
type ComputerBuilder struct {
computer Computer
}
func NewComputerBuilder() *ComputerBuilder {
return &ComputerBuilder{
computer: Computer{
CPU: "Default CPU",
RAM: "8GB",
Storage: "256GB SSD",
},
}
}
func (b *ComputerBuilder) SetCPU(cpu string) *ComputerBuilder {
b.computer.CPU = cpu
return b
}
func (b *ComputerBuilder) SetRAM(ram string) *ComputerBuilder {
b.computer.RAM = ram
return b
}
func (b *ComputerBuilder) SetStorage(storage string) *ComputerBuilder {
b.computer.Storage = storage
return b
}
func (b *ComputerBuilder) Build() Computer {
return b.computer
}
// 使用示例
func main() {
computer := NewComputerBuilder().
SetCPU("Intel i7").
SetRAM("32GB DDR4").
SetStorage("1TB NVMe SSD").
Build()
fmt.Printf("%+v\n", computer) // 输出:{CPU:Intel i7 RAM:32GB DDR4 Storage:1TB NVMe SSD}
}
2. 进阶实现(带指挥者)
type Builder interface {
Reset()
SetCPU(string)
SetRAM(string)
SetStorage(string)
GetComputer() Computer
}
type OfficeComputerBuilder struct {
computer Computer
}
func (b *OfficeComputerBuilder) Reset() {
b.computer = Computer{
CPU: "Intel i3",
RAM: "8GB",
Storage: "512GB HDD",
}
}
func (b *OfficeComputerBuilder) SetCPU(cpu string) {
b.computer.CPU = cpu
}
func (b *OfficeComputerBuilder) SetRAM(ram string) {
b.computer.RAM = ram
}
func (b *OfficeComputerBuilder) SetStorage(storage string) {
b.computer.Storage = storage
}
func (b *OfficeComputerBuilder) GetComputer() Computer {
return b.computer
}
type Director struct{}
func (d *Director) BuildStandardOfficeComputer(b Builder) Computer {
b.Reset()
b.SetCPU("Intel i5")
b.SetRAM("16GB")
b.SetStorage("512GB SSD")
return b.GetComputer()
}
// 使用示例
func main() {
director := Director{}
builder := &OfficeComputerBuilder{}
computer := director.BuildStandardOfficeComputer(builder)
fmt.Printf("%+v\n", computer) // 输出:{CPU:Intel i5 RAM:16GB Storage:512GB SSD}
}
五、关键实现差异对比
六、模式优缺点分析
👍 优点:
分步构建:支持复杂对象的逐步构造
灵活扩展:可创建不同形式的产品
封装细节:隐藏产品的内部表示
参数控制:避免构造函数参数爆炸
👎 缺点:
代码冗余:需要创建多个Builder类
复杂度增加:简单对象可能过度设计
性能损耗:多步骤构建带来额外开销
七、实际应用案例
1. HTTP请求构建
// PHP示例
$request = (new HttpRequestBuilder())
->setMethod('POST')
->setUrl('https://api.example.com')
->setHeaders(['Content-Type' => 'application/json'])
->setBody(json_encode(['key' => 'value']))
->build();
2. 数据库查询构造器
// Go示例
query := NewQueryBuilder().
Select("name", "email").
From("users").
Where("age > ?", 18).
OrderBy("created_at DESC").
Build()
3. 游戏角色创建
$character = (new CharacterBuilder())
->setRace("Elf")
->setClass("Ranger")
->setEquipment("Bow", "Leather Armor")
->setSkills(["Stealth", "Archery"])
->build();
八、与工厂模式的区别
九、总结
建造者模式是构建复杂对象的利器,通过分离构建过程与最终表示,它提供了极大的灵活性和可维护性。无论是PHP的方法链还是Go的函数选项模式,都能优雅地实现这一模式。当面对需要多参数配置的复杂对象时,建造者模式将成为您的首选方案。
在下一篇文章中,我们将探讨 原型模式 及其在对象复制中的应用。敬请期待!
下一篇预告:设计模式系列(五)——原型模式:高效复制的艺术
License:
CC BY 4.0