创建型设计模式-建造者 Builder

简介

建造者模式可将对象的初始化转变成一步步配置的过程。如当对象的初始化时有很多可选参数,建造者模式可以定制参数实现对象的创建。好处有:

  1. 定制对象参数
  2. 针对不同参数,做不同的校验,如当设置了三角形的两个边长,设置第三个边时必须满足两边之和大于第三边的条件。

角色

  • Builder 类

    定义建造一个Product分几个步骤

  • 具体 Builder 类

    实现不同的步骤

  • Director

    属于快速建造某一种产品的方法,如 Director 提供了创建自动挡和手动挡汽车两种方法,创建自动挡汽车中其实是调用 setA setB,而创建自动单汽车中调用setC setD。也可以不使用 Director,直接使用 Builder 的 setA setB 去设置属性

  • 要被实例化的类

    初始化时可定制的参数较多,如 setA setB setC...

类图

图中的 Director 在 make 方法中封装了设置产品属性的步骤,通过传入不同的 builder 类,实现不同的实现步骤,创建不同的产品。

类图
类图

代码

interface Builder
{
    public function producePartA()void;

    public function producePartB()void;

    public function producePartC()void;
}

class ConcreteBuilder1 implements Builder
{
    private $product;

    public function __construct()
    
{
        $this->reset();
    }

    public function reset()void
    
{
        $this->product = new Product1();
    }

    public function producePartA()void
    
{
        $this->product->parts[] = "PartA1";
    }

    public function producePartB()void
    
{
        $this->product->parts[] = "PartB1";
    }

    public function producePartC()void
    
{
        $this->product->parts[] = "PartC1";
    }

    public function getProduct()Product1
    
{
        $result = $this->product;
        $this->reset();

        return $result;
    }
}

/**
 * EN: It makes sense to use the Builder pattern only when your products are
 * quite complex and require extensive configuration.
 *
 * Unlike in other creational patterns, different concrete builders can produce
 * unrelated products. In other words, results of various builders may not
 * always follow the same interface.
 *
 * RU: Имеет смысл использовать паттерн Строитель только тогда, когда ваши
 * продукты достаточно сложны и требуют обширной конфигурации.
 *
 * В отличие от других порождающих паттернов, различные конкретные строители
 * могут производить несвязанные продукты. Другими словами, результаты различных
 * строителей могут не всегда следовать одному и тому же интерфейсу.
 */

class Product1
{
    public $parts = [];

    public function listParts()void
    
{
        echo "Product parts: " . implode(', '$this->parts) . "\n\n";
    }
}

class Director
{
    private $builder;

    public function setBuilder(Builder $builder)void
    
{
        $this->builder = $builder;
    }

    public function buildMinimalViableProduct()void
    
{
        $this->builder->producePartA();
    }

    public function buildFullFeaturedProduct()void
    
{
        $this->builder->producePartA();
        $this->builder->producePartB();
        $this->builder->producePartC();
    }
}

function clientCode(Director $director)
{
    $builder = new ConcreteBuilder1();
    $director->setBuilder($builder);

    echo "Standard basic product:\n";
    $director->buildMinimalViableProduct();
    $builder->getProduct()->listParts();

    echo "Standard full featured product:\n";
    $director->buildFullFeaturedProduct();
    $builder->getProduct()->listParts();

    // 不使用 Director,直接操作 builder 来创建产品
    echo "Custom product:\n";
    $builder->producePartA();
    $builder->producePartC();
    $builder->getProduct()->listParts();
}

$director = new Director();
clientCode($director);

output:

Standard basic product:
Product parts: PartA1

Standard full featured product:
Product parts: PartA1, PartB1, PartC1

Custom product:
Product parts: PartA1, PartC1

本文由 mdnice 多平台发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值