什么是建造者模式
官方解释:使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
个人理解:建造这个词,首先会让我们想到建造一个房子,从零开始,准备混凝土,钢筋,水,砖头等等非常多的材料,用这么多材料最终搭建出一个房子。
使用场景
一个类很多的属性,如果使用构造方法去初始化这些属性,那会很容易出错,想象以下,比如有4个以上的属性,有必填的,有可选的,你每次初始化这个类的时候,都要一个个去校对每个参数的正确性,是不是也是一个令人烦躁的事情,此时就应该用建造者模式。
示意图
优点
易扩展,符合设计原则的单一原则和开闭原则,避免细节性错误
代码实例
目录结构
PackageContact.php 套餐抽象类
<?php
abstract class PackageContact{
//汉堡数量
public $hanbaoNumber;
//可乐数量
public $keleNumber;
//薯条数量
public $shutiaoNumber;
//炸鸡数量
public $zhajiNumber;
//土豆泥数量
public $tudouniNumber;
//番茄酱数量
public $fanqiejiangNumber;
//配置薯条数量
public abstract function setshutiaoNumber();
//配置炸鸡数量
public abstract function setzhajiNumber();
//配置土豆泥数量
public abstract function settudouniNumber();
//配置番茄酱数量
public abstract function setfanqiejiangNumber();
}
Package1.php 套餐1
<?php
class Package1 extends PackageContact{
public function __construct($hanbaoNumber,$keleNumber)
{
$this->hanbaoNumber = $hanbaoNumber;
$this->keleNumber = $keleNumber;
}
public function setshutiaoNumber()
{
// TODO: Implement shutiaoNumber() method.
$this->shutiaoNumber = 1;
return $this;
}
public function setfanqiejiangNumber()
{
// TODO: Implement fanqiejiangNumber() method.
$this->fanqiejiangNumber = 1;
return $this;
}
public function settudouniNumber()
{
// TODO: Implement tudouniNumber() method.
$this->tudouniNumber = 1;
return $this;
}
public function setzhajiNumber()
{
// TODO: Implement zhajiNumber() method.
$this->zhajiNumber = 1;
return $this;
}
}
Package2.php 套餐2
<?php
class Package2 extends PackageContact{
public function __construct($hanbaoNumber,$keleNumber)
{
$this->hanbaoNumber = $hanbaoNumber;
$this->keleNumber = $keleNumber;
}
public function setshutiaoNumber()
{
// TODO: Implement shutiaoNumber() method.
$this->shutiaoNumber = 2;
return $this;
}
public function setfanqiejiangNumber()
{
// TODO: Implement fanqiejiangNumber() method.
$this->fanqiejiangNumber = 2;
return $this;
}
public function settudouniNumber()
{
// TODO: Implement tudouniNumber() method.
$this->tudouniNumber = 2;
return $this;
}
public function setzhajiNumber()
{
// TODO: Implement zhajiNumber() method.
$this->zhajiNumber = 2;
return $this;
}
}
Builder.php 建造者类
<?php
class Builder{
protected $package;
/**
* 设置套餐
* @param PackageContact $package
*/
public function setPackage(PackageContact $package){
$this->package = $package;
}
/**
* 设置套餐内容
* @return $this
*/
public function package(){
$this->package->setshutiaoNumber()->setzhajiNumber()->settudouniNumber()->setfanqiejiangNumber();
return $this;
}
/**
* 获取套餐
*/
public function getPackage(){
echo "<h3>汉堡".$this->package->hanbaoNumber."份</h3>";
echo "<h3>可乐".$this->package->keleNumber."份</h3>";
echo "<h3>薯条".$this->package->shutiaoNumber."份</h3>";
echo "<h3>炸鸡".$this->package->zhajiNumber."份</h3>";
echo "<h3>番茄酱".$this->package->fanqiejiangNumber."份</h3>";
echo "<h3>土豆泥".$this->package->tudouniNumber."份</h3>";
}
}
Client.php 调用
<?php
require_once "Builder.php";
require_once "PackageContact.php";
require_once "Package1.php";
require_once "Package2.php";
echo "<h2>套餐一</h2>";
$package = new Package1(1,2);
$builder = new Builder();
$builder->setPackage($package);
$builder->package();
$builder->getPackage();
echo "分割线---------------------------------------------------------------";
echo "<h2>套餐二</h2>";
$package = new Package2(1,2);
$builder->setPackage($package);
$builder->package();
$builder->getPackage();
运行结果