建造者模式

定义:

  为了将复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。应该考虑建造者模式。

  即对复杂的构建过程和细节进行封装,使用户能更简洁的创建需要的对象。

结构图:

 

 

Product:最终要生成的产品类,就是之前你需要一个个去设置构造函数的那个初始类。就是下面代码例子中的电脑类

Builder:建造者抽象基类,定义构建产品(product)的抽象步骤,其实体子类需要用不同的参数实现这些步骤,以获得不同的产品对象。需要定义一个获取最终产品的方法如下面的【Product GetProduct()】,该方法完全可以放到指挥者中。

ConcreteBuilder:Builder的实现类;就是下面代码中两种型号电脑的建造者。

Director:指挥者,定义组装方法【void Construct(Builder cBuilder)]。这里的组装方法也可以放到builder中,但是为了更好的分离共同部分,才有了这个指挥者。Builder中的【Product GetProduct()】方法也完全可以放到指挥者中。

 

 代码:

//为了使代码更容易理解,这里的具体产品使用电脑来代替(Computer);

Class Computer

{

  //这里cup和ram需要在构造时设如,键盘在需要时设置。

  string cup;

  string ram;

  string keyboard;

  pubilc Computer(string cup,string ram)  

  {

    this.cpu = cup;

    this.ram = ram;

  }

  void SetKeyboard(string keyboard)

  {

    this.keyboard = keyboard;

  }

}

//抽象建造者基类

Class Builder

{

  //设置键盘的抽象方法

  void SetKeyboard(string keyboard) = 0;

  //获取具体型号电脑产品的抽象方法

  Computer* GetProduct() = 0;

}

//苹果电脑建造者类

Class MacBuilder :Builder

{

  Computer* pComputer;

  //初始化具体产品

  public MacBuilder(string cup,string ram

  {

    pComputer = new Computer(string cup,string ram);

  }

  //设置具体键盘

  void SetKeyboard() 

  {

    pComputer->SetKeyboard("苹果键盘");

  }

  //获取具体型号电脑产品

  Computer* GetProduct() 

  {

    return pComputer;

  }

}

//指挥者类

Class Director

{

  //封装组装过程的方法

  void Construct(Builder cBuilder) 

  {

    cBuilder.SetKeyboard();

  } 

}

//客户端

Director* cDirector = new Director();//首先生成一个指挥者

Builder* cBuilder = new MacBuilder("I7","x860");//生成一个具体建造者,用于建造具体产品

cDirector->Construct(&cBuilder);//使用指挥者组装

Computer MacComputer = cBuilder->GetProduct();//获取具体型号产品

 

PS:个人认为指挥者不是必要的,组装过程完全可以在builder中定义;或者获取具体产品的方法也可以放到指挥者中。

  产品类也不是必要的,建造者基类中完全可以定义产品。

  所以该模式还是比较灵活的,重要的只是分离构建和表示。形式不是绝对的。

 

使用时机:

  当你觉得一个类创建过程太复杂,或者频繁被创建固定的几种对象。考虑建造者模式吧。

 

优点:封装和抽象了每个步骤的实现,实现了依赖倒转原则。减少了冗余代码。

缺点:要求构建产品的步骤(算法)是不能剧烈变化的,最好是不变的,这样就影响了灵活度。

posted @ 2020-07-29 00:59  吉尔加斯  阅读(145)  评论(0编辑  收藏  举报