参考:http://www.runoob.com/design-pattern/builder-pattern.html
介绍
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
实现
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo,我们的演示类使用 MealBuilder 来创建一个 Meal。
以下用php代码示例:
<?php
interface Item{
public function name();
public function packing();
public function price();
}
interface Packing{
public function getPack();
}
class Wrapper implements Packing{
public function getPack(){
return 'wrapper';
}
}
class Bottle implements Packing{
public function getPack(){
return 'bottle';
}
}
abstract class Burger implements Item{
public function packing(){
return new Wrapper();
}
}
abstract class ColdDrink implements Item{
public function packing(){
return new Bottle();
}
}
class VegBurger extends Burger{
public function name(){
return 'VegBurger';
}
public function price(){
return 20;
}
}
class ChickenBurger extends Burger{
public function name(){
return 'ChickenBurger';
}
public function price(){
return 40;
}
}
class Pepsi extends ColdDrink{
public function name(){
return 'Pepsi';
}
public function price(){
return 10;
}
}
class Coke extends ColdDrink{
public function name(){
return 'Coke';
}
public function price(){
return 11;
}
}
class Meal{
public $item;
public $price=0;
public $mealList = '';
public function add(Item $item){
$this->item[] = $item;
}
public function getOrder(){
foreach($this->item as $item){
$this->mealList .= "名称:".$item->name()."\n";
$this->mealList .= "价格:".$item->price()."\n";
$this->mealList .= "包装:".$item->packing()->getPack()."\n\n";
$this->price += $item->price();
}
$this->mealList .= "\n总计:" . $this->price ."\n\n";
print_r($this->mealList);
}
}
class MealBuilder extends Meal{
public function a1(){
$this->add(new VegBurger());
$this->add(new Pepsi());
}
public function a2(){
$this->add(new ChickenBurger());
$this->add(new Pepsi());
}
public function b1(){
$this->add(new ChickenBurger());
$this->add(new Coke());
}
public function b2(){
$this->add(new ChickenBurger());
$this->add(new Coke());
}
public function free($arr)
{
foreach($arr as $item){
$this->add($item);
}
}
}
$mealBuilder = new MealBuilder();
$mealBuilder->a1();
$mealBuilder->getOrder();
$mealBuilder2 = new MealBuilder();
$mealBuilder2->free([new VegBurger(),new ChickenBurger(),new Pepsi()]);
$mealBuilder2->getOrder();
上面的例子比较灵活,但不是太侧重“同样的构建过程”。比较常见的是下面这种只有一个产品的模式结构,大多数的书中也是这样讲的。
参考:https://blog.csdn.net/xingjiarong/article/details/50037099
在实际的应用中不可能只用创建者模式创建一种产品如。
以汽车构建为例:
<?php
interface engine{
public function getEngine();
}
interface wheel{
public function getWheel();
}
interface body{
public function getBody();
}
class AudiEngine implements engine{
public function getEngine(){
return '奥迪引擎';
}
}
class BaomaEngine implements engine{
public function getEngine(){
return '宝马引擎';
}
}
class AudiWheel implements wheel{
public function getWheel(){
return '奥迪车轮';
}
}
class BaomaWheel implements wheel{
public function getWheel(){
return '宝马车轮';
}
}
class AudiBody implements body{
public function getBody(){
return '奥迪车身';
}
}
class BaomaBody implements body{
public function getBody(){
return '宝马车身';
}
}
class CarProduct{
public $engine;
public $wheel;
public $body;
}
abstract class CarBuilder{
protected $car;
public function __construct(){
$this->car = new CarProduct();
}
public abstract function buildEngine();
public abstract function buildWheel();
public abstract function buildBody();
public function getCar(){
return $this->car;
}
}
class AudiBuilder extends CarBuilder{
public function buildEngine(){
$this->car->engine = new AudiEngine();
}
public function buildWheel(){
$this->car->wheel = new AudiWheel();
}
public function buildBody(){
$this->car->body = new AudiBody();
}
}
class BaomaBuilder extends CarBuilder{
public function buildEngine(){
$this->car->engine = new BaomaEngine();
}
public function buildWheel(){
$this->car->wheel = new BaomaWheel();
}
public function buildBody(){
$this->car->body = new BaomaBody();
}
}
class director{
public function createCar(CarBuilder $car){
//通常的做法是buildEngine($car),在buildEngine根据不同的car参数做不同的处理
//如此会把所有的业务逻辑都压在createCar模块。
//使用构造方法,可解耦此逻辑,各自car的buildEngine各自处理
$car->buildEngine();
$car->buildWheel();
$car->buildBody();
return $car;
}
}
$carBuilder = new AudiBuilder();
// $carBuilder = new BaomaBuilder();
$director = new director();
$car = $director->createCar($carBuilder);
var_dump($car->getCar()->engine->getEngine());
var_dump($car->getCar()->wheel->getWheel());
var_dump($car->getCar()->body->getBody());