建造者模式
建造者模式(Builder Pattern)使用多個簡單的對象一步一步構建成一個復雜的對象收厨。這種類型的設計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式砸讳。
一個 Builder 類會一步一步構造最終的對象琢融。該 Builder 類是獨立于其他對象的。
介紹
意圖:將一個復雜的構建與其表示相分離簿寂,使得同樣的構建過程可以創(chuàng)建不同的表示漾抬。
主要解決:主要解決在軟件系統(tǒng)中,有時候面臨著"一個復雜對象"的創(chuàng)建工作常遂,其通常由各個部分的子對象用一定的算法構成纳令;由于需求的變化,這個復雜對象的各個部分經(jīng)常面臨著劇烈的變化烈钞,但是將它們組合在一起的算法卻相對穩(wěn)定泊碑。
何時使用:一些基本部件不會變,而其組合經(jīng)常變化的時候毯欣。
如何解決:將變與不變分離開馒过。
關鍵代碼:建造者:創(chuàng)建和提供實例,導演:管理建造出來的實例的依賴關系酗钞。
應用實例: 1腹忽、去肯德基,漢堡砚作、可樂窘奏、薯條、炸雞翅等是不變的葫录,而其組合是經(jīng)常變化的着裹,生成出所謂的"套餐"。 2米同、JAVA 中的 StringBuilder骇扇。
優(yōu)點: 1摔竿、建造者獨立,易擴展少孝。 2继低、便于控制細節(jié)風險。
缺點: 1稍走、產(chǎn)品必須有共同點袁翁,范圍有限制绿贞。 2获列、如內(nèi)部變化復雜,會有很多的建造類溯警。
建造者模式包括的角色:
(1)Builder:給出一個抽象接口或抽象類盖淡,以規(guī)范產(chǎn)品的建造年柠。這個接口規(guī)定要實現(xiàn)復雜對象的哪些部分的創(chuàng)建,并不涉及具體的對象部件的創(chuàng)建褪迟,一般由子類具體實現(xiàn)。
(2)ConcreteBuilder:Builder接口的實現(xiàn)類答憔,并返回組建好對象實例味赃。
(3)Director:調(diào)用具體建造者來創(chuàng)建復雜對象的各個部分,在指導者中不涉及具體產(chǎn)品的信息虐拓,只負責保證對象各部分完整創(chuàng)建或按某種順序創(chuàng)建心俗。
(4)Product:要創(chuàng)建的復雜對象,產(chǎn)品類蓉驹。
建造者模式的使用場景:
(1)當產(chǎn)品有復雜的內(nèi)部構造時(參數(shù)很多)城榛。
(2)需要生產(chǎn)的產(chǎn)品的屬性相互依賴,這些屬性的賦值順序比較重要時(因為在調(diào)用ConcreteBuilder的賦值方法時是有先后順序的)态兴。
注意事項:與工廠模式的區(qū)別是:建造者模式更加關注與零件裝配的順序狠持。
案例一
下面是利用建造者模式“組裝一臺電腦”的實現(xiàn)方式,便于理解該模式如何運用瞻润。
1.產(chǎn)品類
要組裝一臺電腦(Computer類)喘垂,我們假設它有三個部件:CPU 、主板以及內(nèi)存绍撞。
在Computer類中提供三個set方法分別設置這三個屬性正勒。
public class Computer {
private String mCpu;
private String mMainboard;
private String mRam;
public void setmCpu(String mCpu) {
this.mCpu = mCpu;
}
public void setmMainboard(String mMainboard) {
this.mMainboard = mMainboard;
}
public void setmRam(String mRam) {
this.mRam = mRam;
}
}
2 .Builder類
下面就是一個抽象的Builder類,里面提供了安裝CPU傻铣、主板和內(nèi)存的抽象方法章贞,以及組裝成電腦的create方法。
public abstract class Builder {
public abstract void buildCpu(String cpu);
public abstract void buildMainboard(String mainboard);
public abstract void buildRam(String ram);
public abstract Computer create();
}
3. Builder實現(xiàn)類
下面是一個繼承Builder的子類非洲,里面不僅新建了Computer的實例鸭限,還提供了安裝CPU就谜、主板和內(nèi)存的具體實現(xiàn)方法,并且在組裝成電腦的create方法中將該Computer對象實例返回里覆。
public class MyComputerBuilder extends Builder {
private Computer mComputer = new Computer();
@Override
public void buildCpu(String cpu) {
mComputer.setmCpu(cpu);
}
@Override
public void buildMainboard(String mainboard) {
mComputer.setmMainboard(mainboard);
}
@Override
public void buildRam(String ram) {
mComputer.setmRam(ram);
}
@Override
public Computer create() {
return mComputer;
}
}
4 .Director類
指揮者(Director)類用來規(guī)范組裝電腦的流程順序丧荐,先安裝主板,再安裝CPU喧枷,最后安裝內(nèi)存并組裝成電腦虹统。
public class Direcror {
Builder mBuild=null;
public Direcror(Builder build){
this.mBuild=build;
}
public Computer CreateComputer(String cpu,String mainboard,String ram){
//規(guī)范建造流程,這個順序是由它定的
this.mBuild.buildMainboard(mainboard);
this.mBuild.buildCpu(cpu);
this.mBuild.buildRam(ram);
return mBuild.create();
}
}
5.使用
Builder mBuilder = new MyComputerBuilder();
Direcror mDirecror=new Direcror(mBuilder);
mDirecror.CreateComputer("i7","Intel主板","mRam");//返回Computer實例對象
以上便完成了整個建造者模式的實現(xiàn)細節(jié)隧甚。
建造者模式精簡版
在現(xiàn)實開發(fā)中车荔,往往省去Director的角色,而直接使用一個Buider實例來進行對象的組裝戚扳。
建造者模式優(yōu)缺點
建造者模式的優(yōu)點:
(1)建造模式是將復雜的內(nèi)部創(chuàng)建封裝在內(nèi)部忧便,對于外部調(diào)用的人來說,只需要傳入建造者和建造工具帽借,對于內(nèi)部是如何建造成成品的珠增,調(diào)用者無需關心,良好的封裝性是建造者模式的優(yōu)點之一砍艾。
(2)建造者類邏輯獨立蒂教,易拓展。
建造者模式的缺點:
很明顯產(chǎn)生了多余的Build對象以及Dirextor對象脆荷,消耗了內(nèi)存凝垛。
實例二
參與者
1.Builder
為創(chuàng)建一個Product對象的各個部件指定抽象接口。
2.ConcreteBuilder
實現(xiàn)Builder的接口以構造和裝配該產(chǎn)品的各個部件蜓谋。
定義并明確它所創(chuàng)建的表示梦皮。
提供一個檢索產(chǎn)品的接口。
3.Director
構造一個使用Builder接口的對象桃焕。
4.Product
表示被構造的復雜對象剑肯。ConcreteBuilder創(chuàng)建該產(chǎn)品的內(nèi)部表示并定義它的裝配過程。
包含定義組成部件的類覆旭,包括將這些部件裝配成最終產(chǎn)品的接口退子。
類圖
1.Builder
package com.nieshenkuan.creational.builderPattern.demo;
public interface PersonBuilder {
void buildHead();
void buildBody();
void buildFoot();
Person buildPerson();
}
2.ConcreteBuilder
package com.nieshenkuan.creational.builderPattern.demo;
public class ManBuilder implements PersonBuilder {
Person person;
public ManBuilder() {
person = new Man();
}
public void buildBody() {
person.setBody("建造男人的身體");
}
public void buildFoot() {
person.setFoot("建造男人的腳");
}
public void buildHead() {
person.setHead("建造男人的頭");
}
public Person buildPerson() {
return person;
}
}
3.Director
package com.nieshenkuan.creational.builderPattern.demo;
public class PersonDirector {
public Person constructPerson(PersonBuilder pb) {
pb.buildHead();
pb.buildBody();
pb.buildFoot();
return pb.buildPerson();
}
}
4.Product
package com.nieshenkuan.creational.builderPattern.demo;
public class Person {
private String head;
private String body;
private String foot;
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
}
package com.nieshenkuan.creational.builderPattern.demo;
public class Man extends Person{
}
5.Test
package com.nieshenkuan.creational.builderPattern.demo;
public class Test {
public static void main(String[] args) {
PersonDirector pd = new PersonDirector();
Person person = pd.constructPerson(new ManBuilder());
System.out.println(person.getBody());
System.out.println(person.getFoot());
System.out.println(person.getHead());
}
}
結果:
建造男人的身體
建造男人的腳
建造男人的頭
2018/04/25