GoF类图

建造者模式

代码实现

php建造者模式PHP设计模式之建造者模式 PHP

classProduct{private$parts=[];publicfunctionAdd(String$part):void{$this->parts[]=$part;}publicfunctionShow():void{echoPHP_EOL.'产品创建----',PHP_EOL;foreach($this->partsas$part){echo$part,PHP_EOL;}}}

产品类,你可以把它想象成我们要建造的屋子。
这时的屋子还没有任何内容,我们须要给它添砖加瓦。

interfaceBuilder{publicfunctionBuildPartA():void;publicfunctionBuildPartB():void;publicfunctionGetResult():Product;}classConcreteBuilder1implementsBuilder{private$product;publicfunction__construct(){$this->product=newProduct();}publicfunctionBuildPartA():void{$this->product->Add('部件A');}publicfunctionBuildPartB():void{$this->product->Add('部件B');}publicfunctionGetResult():Product{return$this->product;}}classConcreteBuilder2implementsBuilder{private$product;publicfunction__construct(){$this->product=newProduct();}publicfunctionBuildPartA():void{$this->product->Add('部件X');}publicfunctionBuildPartB():void{$this->product->Add('部件Y');}publicfunctionGetResult():Product{return$this->product;}}

建造者抽象及实在现。
不同的开拓商总会选用不同的品牌材料,这里我们有了两个不同的开拓商,但他们的目的同等,都是为了去盖屋子(Product)。

classDirector{publicfunctionConstruct(Builder$builder){$builder->BuildPartA();$builder->BuildPartB();}}

布局器,用来调用建造者进行生产。
没错,便是我们的工程队。
它来选取材料并进行建造。
同样的工程队,可以接不同的单,但盖出来的都是屋子。
只是这个屋子的材料和外不雅观不同,大体上的手艺还是共通的。

$director=newDirector();$b1=newConcreteBuilder1();$b2=newConcreteBuilder2();$director->Construct($b1);$p1=$b1->getResult();$p1->Show();$director->Construct($b2);$p2=$b2->getResult();$p2->Show();

末了看看我们的实现,是不是非常大略,准备好工程队,准备好不同的建造者,然后交给工程队去生产就好啦!

实在这个模式要办理的最紧张问题便是一个类可能有非常多的配置、属性,这些配置、属性也并不全是必须要配置的,一次性的实例化去配置这些东西非常麻烦。
这时就可以考虑让这些配置、属性变成一个一个可随时添加的部分。
通过不同的属性组合拿到不同的工具。
上面那一条,在GoF那里的原文是:它使你改变一个产品的内部表示;它将布局代码和表示代码分开;它使你可以对布局过程进行更风雅的掌握。
再说得大略一点,工具太繁芜,我们可以一部分一部分的拼装它!
理解过一点Android开拓的一定不会陌生,创建对话框工具AlterDialog.builderLaravel中,数据库组件也利用了建造者模式,你可以翻看下源码中Database\Eloquent和Database\Query目录中是否都有一个Builder.php

大家都知道,手机组装是一件繁芜的过程,于是,不同型号的手机我们都有对应的图纸(Builder),将图纸和配件交给流水线上的工人(Director),他们就会根据图纸利用配件光降盆出我们所须要的各种不同型号的手机(Product)。
很明显,我们都是伟大的建造者,为我们的家当添砖加瓦!


完全代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/16.builder/source/builder.php

实例

前面说过Android中有很多Dialog对话框都会用建造者模式来实现,作为一家手机厂的老板,定制化的Android系统也是非常主要的一个部分。
就像X米一样,从MIUI入手,先拿下了软件市场,让大家以为这个别系非常好用,然后再开始开拓手机。
这就解释软硬件的确是当代手机的两大最主要的组成部分,缺了谁都弗成。
这回,我们就用建造者模式大略的实现一套对话框组件吧!

对话框类图

对话框功能建造者模式版

完全源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/16.builder/source/builder-dialog.php

<?phpclassDialog{private$attributes=[];private$buttons=[];private$title='';private$content='';publicfunctionAddAttributes($attr){$this->attributes[]=$attr;}publicfunctionAddButtons($button){$this->buttons[]=$button;}publicfunctionSetTitle($title){$this->title=$title;}publicfunctionSetContent($content){$this->content=$content;}publicfunctionShowDialog(){echoPHP_EOL,'显示提示框===',PHP_EOL;echo'标题:'.$this->title,PHP_EOL;echo'内容:'.$this->content,PHP_EOL;echo'样式:'.implode(',',$this->attributes),PHP_EOL;echo'按扭:'.implode(',',$this->buttons),PHP_EOL;}}interfaceBuilder{publicfunctionBuildAttribute($attr);publicfunctionBuildButton($button);publicfunctionBuildTitle($title);publicfunctionBuildContent($content);publicfunctionGetDialog();}classDialogBuilderimplementsBuilder{private$dialog;publicfunction__construct(){$this->dialog=newDialog();}publicfunctionBuildAttribute($attr){$this->dialog->AddAttributes($attr);}publicfunctionBuildButton($button){$this->dialog->AddButtons($button);}publicfunctionBuildTitle($title){$this->dialog->SetTitle($title);}publicfunctionBuildContent($content){$this->dialog->SetContent($content);}publicfunctionGetDialog(){return$this->dialog;}}classDialogDirector{publicfunctionConstruct($title,$content){$builder=newDialogBuilder();$builder->BuildAttribute('置于顶层');$builder->BuildAttribute('居中显示');$builder->BuildButton('确认');$builder->BuildButton('取消');$builder->BuildTitle($title);$builder->BuildContent($content);return$builder;}}classModalDialogDirector{publicfunctionConstruct($title,$content){$builder=newDialogBuilder();$builder->BuildAttribute('置于顶层');$builder->BuildAttribute('居中显示');$builder->BuildAttribute('背景庶照');$builder->BuildAttribute('外部无法点击');$builder->BuildButton('确认');$builder->BuildButton('取消');$builder->BuildTitle($title);$builder->BuildContent($content);return$builder;}}$d1=newDialogDirector();$d1->Construct('窗口1','确认要实行操作A吗?')->GetDialog()->ShowDialog();$d2=newModalDialogDirector();$d2->Construct('窗口2','确认要实行操作B吗?')->GetDialog()->ShowDialog();

解释

这回我们的产品就有点繁芜了,有标题、内容、属性、按扭等建造过程实在都一样,但这里我们紧张利用了不同的布局器。
普通对话框表面的东西是可以点击的,而模态窗口一样平常会有遮罩层,便是背景变成透明黑,而且表面的东西是不能再点击的如果每次都直接通过布局方法去实例化窗口类,那要通报的参数会很多,而现在这样,我们就可以通过建造者来进行组合,让工具具有多态的效果,能够呈现不同的形态及功能下期看点

建造者模式真的非常常用,虽说我们平常写的代码中可能用得比较少,但在很多框架或者大型系统的架构中都会有它的身影。
我们希望类都是大略的,小巧的,但大型类的涌现总是不可避免的,这个时候,建造者模式就能发挥它的浸染,让我们能够轻松的构建繁芜、大型的工具。
好吧,不要忘了我们的文章还在连续,如果喜好的话要记得关注公众号或者掘金主页哦,如果怕忘了,不妨写个备忘录哦。