想象一下,我们要组装一台台式电脑,我们需要选择机箱,主板类型,CPU类型,硬盘类型等等。然后根据选择的配件,一步一步组合起来,最后变成一台可运行的电脑。
每个人对电脑的要求不一样,有些人只需要普通办公娱乐的家庭版配置,而些游戏爱好者,因为游戏要玩的流畅舒服爽,就需要高配置的游戏版配置等等。
考虑一下如果要实现不同版本的电脑配置,代码要如何实现
我想到的第一方法就是通过前段时间说过的模板方法实现。模板方法可以让你抽象除创建过程的步骤,而具体的步骤有子类具体实现。代码如下:
//模板模式实现
abstract class ComputerTemplate {
private $_memory = null;
private $_videoCard = null;
private $_processor = null;
public function getComputer() {
echo $this->_memory.'-'.$this->_videoCard.'-'.$this->_processor;
}
public function build() { //组装电脑
$this->_memory = $this->getMemory();
$this->_videoCard = $this->getVideoCard();
$this->_processor = $this->getProcessor();
}
public abstract function getMemory();//内存
public abstract function getVideoCard();//显卡
public abstract function getProcessor(); //CPU
}
//家庭版
class FamilyComputer extends ComputerTemplate {
public function getMemory() {
return "Family Memory";
}
public function getVideoCard() {
return "Family Memory";
}
public function getProcessor() {
return "Family Memory";
}
}
//游戏版版
class GameComputer extends ComputerTemplate {
public function getMemory() {
return "Game Memory";
}
public function getVideoCard() {
return "Game Memory";
}
public function getProcessor() {
return "Game Memory";
}
}
而第二种方法就是我们今天的主角--生成器模式。其实生成器模式,实现的方式和模板模式相似,不过有一些区别。生成器模式,主要是把表示和建造过程分离,然后通过指导者去进行组合。
代码如下:
//电脑最终产品(表示)
class Computer {
private $_memory = null;
private $_videoCard = null;
private $_processor = null;
public function getComputer() {
echo $this->_memory.'-'.$this->_videoCard.'-'.$this->_processor;
}
//内存
public function setMemory($memory){
$this->_memory = $memory;
}
//显卡
public function setVideoCard($videoCard) {
$this->_videoCard = $videoCard;
}
//处理器
public function setProcessor($processor) {
$this->_processor = $processor;
}
}
//电脑创建
abstract class IBuilderComputer {
private $_computer = null;
public function initComputer() {
$this->_computer = new Computer();
}
public function getComputer() {
return $this->_computer;
}
public abstract function buildMemory();
public abstract function buildVideoCard();
public abstract function buildProcessor();
}
//家庭版电脑组装
class FamilyBuilder extends IBuilderComputer {
public function buildMemory() {
$computer = $this->getComputer();
$computer->setMemory("Memory 8G");
}
public function buildVideoCard() {
$computer = $this->getComputer();
$computer->setMemory("Family buildVideoCard");
}
public function buildProcessor() {
$computer = $this->getComputer();
$computer->setProcessor("Family buildVideoCard");
}
}
//家庭版电脑组装
class GameBuilder extends IBuilderComputer {
public function buildMemory() {
$computer = $this->getComputer();
$computer->setMemory("Memory 16G");
}
public function buildVideoCard() {
$computer = $this->getComputer();
$computer->setMemory("Game buildVideoCard");
}
public function buildProcessor() {
$computer = $this->getComputer();
$computer->setProcessor("Game buildVideoCard");
}
}
class Director {
public function build(IBuilderComputer $build) { //指导者,复杂创建过程
$build->initComputer();
$build->buildMemory();
$build->buildVideoCard();
$build->buildProcessor();
return $build->getComputer();
}
}
$Director = new Director();
$GameBuilder = new GameBuilder();
$FamilyBuilder = new FamilyBuilder();
$computer = $Director->build($GameBuilder);
echo $computer->getComputer();
echo "<br>";
$computer2 = $Director->build($FamilyBuilder);
echo $computer2->getComputer();
首先生成器模式的目的是:将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示 使用生成器模式可以使客户端不必知道产品内部组成的细节。
模板模式与生成器模式的对比:
其实模板方式和生成器模式的思想是差不多,都是要抽离出公共部分。只是两者的目的和实现方式有所区别,区别如下
1.生成器模式是使用组合方式实现不同的表示,而模板方法使用的是继承的方式。组合优于继承。
2.生成器模式抽象的是构建过程,而模板方法提取的是公共实现。
抽象工厂模式与生成器模式的对比:
Abstract Factory (抽象工厂)与 Builder(生成器模式)相似,因为它也可以创建复杂对象。主要的区别是
B u i l d e r模式着重于一步步构造一个复杂对象。而 Abstract Factory着重于多个系列的产品对象(简单的或是复杂的)。 B u i l d e r在最后的一步返回产品,而对于 Abstract Factory来说,产品是立即返回的