## 定义
    将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。

## 设计的原则和思想
1. 解耦了对象的创建和使用。
2. 不变部分是使用，变化部分是创建。
3. 核心思想是通过控制对象构建的步骤与顺序来创建复杂的对象。

## 一句话概括设计模式
    通过分解构建步骤，控制构建顺序的方式创建对象。

## 结构中包含的角色
1. Builder（抽象建造者）
2. ConcreteBuilder（具体建造者）
3. Product（产品角色）
4. Director（指挥者）

## 最小可表达代码
    // 需要构建的产品
    class WebProduct
    {
        private $language;

        public  function setLanguage(String $language)
        {
            $this->language  = $language;
        }
    }

    // 抽象构建者
    abstract class BaseBuilder
    {
        protected  $webProduct;

        public function __construct()
        {
            $this->webProduct = new WebProduct();
        }

        public abstract function  buildLanguage();

        public function makeProduct()
        {
            return $this->webProduct;
        }
    }

    // 具体构建者
    class PHPBuilder extends BaseBuilder
    {
        public function buildLanguage()
        {
            $this->webProduct->setLanguage('php');
        }
    }

    // 指挥者
    class WebDirector
    {
        public function make(BaseBuilder $builder)
       {
        	$builder->buildLanguage();

        	return $builder->makeProduct();
       }
    }

    $product = (new WebDirector())->make(new PHPBuilder());
    var_dump($product);

## 优点
1. 将复杂产品的创建步骤分解在不同方法中，使得创建过程更加清晰，方便控制。
2. 具体建造者间相互独立，若想增减时无须修改其他代码。

## 缺点
1. 创建的产品必须有共同点，范围有限制。 
2. 产品的内部变化复杂，会导致需要定义很多具体建造者类来实现这种变化，导致系统变得很庞大

## 何时使用
1. 生成的对象具有复杂的内部结构。
2. 需要生成的产品对象的属性相互依赖，需要指定其生成顺序。
3. 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类，将创建过程封装在指挥者类中，而不在建造者类和客户类中。

## 实际应用场景
1. JAVA 中的 StringBuilder。
2. 商城的商品，收藏的商品，浏览过的商品，推荐的商品。可以使用建造者模式构建商品创建的过程。
