文章目錄
- 23種設計模式——建造者模式
-
- 1、建造者模式概述
- 2、建造者模式的結構
- 3、建造者模式的實作
-
- 3.1、正常實作
- 3.2、更為靈活的實作
- 4、建造者模式和工廠模式的差別
23種設計模式——建造者模式
1、建造者模式概述
建造者(Builder)模式的定義:指将一個複雜對象的構造與它的表示分離,使同樣的建構過程可以建立不同的表示,這樣的設計模式被稱為建造者模式。它是将一個複雜的對象分解為多個簡單的對象,然後一步一步建構而成。它将變與不變相分離,即産品的組成部分是不變的,但每一部分是可以靈活選擇的。
該模式的主要優缺點如下:
- 封裝性好,建構和表示分離。
- 擴充性好,各個具體的建造者互相獨立,有利于系統的解耦。
- 用戶端不必知道産品内部組成的細節,建造者可以對建立過程逐漸細化,而不對其它子產品産生任何影響,便于控制細節風險。
其缺點如下:
- 産品的組成部分必須相同,這限制了其使用範圍。
- 如果産品的内部變化複雜,如果産品内部發生變化,則建造者也要同步修改,後期維護成本較大。
建造者(Builder)模式和工廠模式的關注點不同:建造者模式注重零部件的組裝過程,而工廠方法模式更注重零部件的建立過程,但兩者可以結合使用。
應用場景:
- 相同的方法,不同的執行順序,産生不同的結果。
- 多個部件或零件,都可以裝配到一個對象中,但是産生的結果又不相同。
- 産品類非常複雜,或者産品類中不同的調用順序産生不同的作用。
- 初始化一個對象特别複雜,參數多,而且很多參數都具有預設值。
2、建造者模式的結構
建造者(Builder)模式的主要角色如下。
- 産品角色(Product):它是包含多個組成部件的複雜對象,由具體建造者來建立其各個零部件。
- 抽象建造者(Builder):它是一個包含建立産品各個子部件的抽象方法的接口/抽象類,通常還包含一個傳回複雜産品的方法 getResult()。
- 具體建造者(Concrete Builder):實作 Builder 接口,完成複雜産品的各個部件的具體建立方法。
- 指揮者(Director):它調用建造者對象中的部件構造與裝配方法完成複雜對象的建立,在指揮者中不涉及具體産品的資訊。
建造者模式的結構圖:
3、建造者模式的實作
3.1、正常實作
具體的産品類,包含多個組成部件
public class Product {
//有ABCD多個部件
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
抽象建造者,包含建立産品各個子部件的抽象方法
//抽象的建造者
public abstract class Builder {
//具體産品的各個子部件的抽象方法
abstract void buildA();//部件A
abstract void buildB();//部件B
abstract void buildC();//部件C
abstract void buildD();//部件B
//傳回具體産品的方法
abstract Product getProduct();
}
具體建造者1,實作 Builder 接口,完成複雜産品的各個部件的具體建立方法。
//具體建造者,實作抽象建造者,完成複雜産品的各個部件的具體建立方法
public class Worker extends Builder{
private Product product; //提升作用域
//通過具體建造者的構造器生成具體産品的對象
public Worker(){
product = new Product();
}
@Override
void buildA() {
product.setBuildA("完成部件A");
System.out.println("完成部件A");
}
@Override
void buildB() {
product.setBuildB("完成部件B");
System.out.println("完成部件B");
}
@Override
void buildC() {
product.setBuildC("完成部件C");
System.out.println("完成部件C");
}
@Override
void buildD() {
product.setBuildD("完成部件D");
System.out.println("完成部件D");
}
@Override
Product getProduct() {
System.out.println("完成産品ABCD的建立");
return product;
}
}
具體建造者2,實作 Builder 接口,完成複雜産品的各個部件的具體建立方法。
public class WorkerTwo extends Builder{
private Product product;
public WorkerTwo(){
product = new Product();
}
@Override
void buildA() {
product.setBuildA("完成部件A2");
System.out.println("完成部件A2");
}
@Override
void buildB() {
product.setBuildB("完成部件B2");
System.out.println("完成部件B2");
}
@Override
void buildC() {
product.setBuildC("完成部件C2");
System.out.println("完成部件C2");
}
@Override
void buildD() {
product.setBuildD("完成部件D2");
System.out.println("完成部件D2");
}
@Override
Product getProduct() {
System.out.println("完成産品ABCDTWO的建立");
return product;
}
}
指揮者,調用建造者對象中的部件構造與裝配方法完成複雜對象的建立
public class Director {
//調用建造者對象中的部件構造與裝配方法完成複雜對象的建立
public Product construct(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
客戶類,實作具體建造者1
public class Client {
public static void main(String[] args) {
Director director = new Director();
Product build = director.construct(new Worker());//實作具體建造者1
System.out.println(build.toString());
}
}
測試:
客戶類,實作具體建造者2
public class Client {
public static void main(String[] args) {
Director director = new Director();
Product build = director.construct(new WorkerTwo());
System.out.println(build.toString());
}
}
測試:
上面示例是 Builder模式的正常用法,指揮者類 Director 在 Builder模式中具有很重要的作用,它用于指導具體建構者如何建構産品,控制調用先後次序,并向調用者傳回完整的産品類,但是有些情況下需要簡化系統結構,可以把Director和抽象建造者進行結合。
3.2、更為靈活的實作
産品–>套餐
public class Product {
//預設套餐
private String BuildA = "漢堡";
private String BuildB = "薯條";
private String BuildC = "炸雞";
private String BuildD = "可樂";
public String getBuildA() {
return BuildA;
}
public void setBuildA(String buildA) {
BuildA = buildA;
}
public String getBuildB() {
return BuildB;
}
public void setBuildB(String buildB) {
BuildB = buildB;
}
public String getBuildC() {
return BuildC;
}
public void setBuildC(String buildC) {
BuildC = buildC;
}
public String getBuildD() {
return BuildD;
}
public void setBuildD(String buildD) {
BuildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + BuildD + '\'' +
'}';
}
}
抽象建造類
public abstract class Builder {
abstract Builder buildA(String msg);//漢堡
abstract Builder buildB(String msg);//薯條
abstract Builder buildC(String msg);//炸雞
abstract Builder buildD(String msg);//可樂
//傳回具體的套餐
abstract Product getProduct();
}
具體建造者–>服務員
public class Worker extends Builder{
private Product product;
public Worker() {
product = new Product();
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
客戶:實作預設套餐
public class Client {
public static void main(String[] args) {
Worker worker = new Worker();
Product product = worker.getProduct();
System.out.println(product.toString());
}
}
測試:
實作自選套餐:
public class Client {
public static void main(String[] args) {
Worker worker = new Worker();
Product product = worker
.buildA("蛋糕")
.buildB("雞腿")
.buildC("")
.buildD("")
.getProduct();
System.out.println(product.toString());
}
}
測試:
4、建造者模式和工廠模式的差別
- 建造者模式更加注重方法的調用順序,工廠模式注重建立對象。
- 建立對象的力度不同,建造者模式建立複雜的對象,由各種複雜的部件組成,工廠模式建立出來的對象都一樣
- 關注重點不一樣,工廠模式隻需要把對象建立出來就可以了,而建造者模式不僅要建立出對象,還要知道對象由哪些部件組成。
- 建造者模式根據建造過程中的順序不一樣,最終對象部件組成也不一樣。