设计模式学习系列——建造者模式  建造者模式

  建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。

  优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

  缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

  与 工厂模式区别:

    1)工厂模式关注的是一个整体,无需关注产品各部分是如何创建出来的;建造者模式中,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象”。

  关于选用:如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

  角色:

  •  抽象建造者
  • 具体建造者
  • 指挥者
  • 产品
  • 产品消费者

  具体实例:还是用之前去宠物市场的例子吧(以便和工厂模式做个对比)。养宠物需要有宠物和食物。会是和抽象工厂模式一个完全不同的代码结构。参考代码(php版):

<?php
/*
 * 建造者方法模式示例
 */
error_reporting(E_ALL);
ini_set('display_errors','on');

    /*
     * 具体产品(一个包含宠物和宠物食物的产品)
     */
    class PetGroup{
        private $petType;
        private $food;
        private $foodNum = 0;
        
        public function addPet($petType){
            $this->petType = $petType;
        }
        public function addFood($food,$foodNum){
            $this->food = $food;
            $this->foodNum = $foodNum;
        }
        public function addFish($foodNum){//加鱼
            $this->food = "fish";
            $this->foodNum = $foodNum;
        }   
        public function addBone($foodNum){//加骨头
            $this->food = "bone";
            $this->foodNum = $foodNum;
        }
        public function getPetType(){
            return $this->petType;
        }
        public function getFood(){
            return $this->food;
        }        
    }
    
    /*
     * 抽象建造者
     */
    abstract class Builder{
        //实际的产品,这里的petGroup定义为一个包含宠物和宠物食物的产品
        private $petGroup;  
        //建造宠物
        abstract public function buildPet();
        //建造食物
        abstract public function buildFood($num);
        
        public function createPetGroup(){
            $this->petGroup = new PetGroup();
        }
        public  function getPetGroup(){
            return $this->petGroup;
        }
    }
    
    /*
     * 具体建造者(猫宠物组合)
     */
    class CatGroupBuilder extends Builder{
        
        public  function buildPet(){
            $this->getPetGroup()->addPet("cat");
        }
        public function buildFood($num){
            $this->getPetGroup()->addFish($num);
        }        
    } 
    
    /*
     * 具体建造者(狗宠物组合)
     */
    class DogGroupBuilder extends Builder{
        
        public  function buildPet(){
            $this->getPetGroup()->addPet("dog");
        }
        public  function buildFood($num){
            $this->getPetGroup()->addBone($num);
        }        
    }
    
    /*
     * 指挥者
     */
     class Director{
         private $builder;
         public function __construct($builder) {
             $this->builder = $builder;
         }
         public function getBuilder(){
             return $this->builder;
         }
         public function setBuilder($builder){
             $this->builder = $builder;
         }         
         public function getPetGroup(){
             $this->builder->createPetGroup();
             $this->builder->buildPet();
             $this->builder->buildFood(5);
             return $this->builder->getPetGroup();
         }
     }

     $catGroupBuilder = new CatGroupBuilder();
     $director = new Director($catGroupBuilder);
     $catGroup = $director->getPetGroup();
     echo $catGroup->getPetType()." ".$catGroup->getFood()."<br/>";//cat fish
     $dogGroupBuilder = new DogGroupBuilder();
     $director->setBuilder($dogGroupBuilder);
     $dogGroup = $director->getPetGroup();
     echo $dogGroup->getPetType()." ".$dogGroup->getFood()."<br/>";//dog bone

?>
View Code

  对比工厂模式中的抽象工厂会看到,从消费者的角度:抽象工厂模式先让你选择 一个产品加工厂,加工厂可以建造一套产品的各个产品族(宠物和食物);而建造者模式,会首先有一个指挥者,把你想要生产的一套产品告诉指挥者,指挥者去组装这套产品,交给消费者。(建造者模式更注重组装的这个过程)

  

参考资料:

【设计模式】 模式PK:工厂模式VS建造者模式

【设计模式】建造者模式(生成器模式)

建造者模式