【1】基本概念
建造(Builder)模式是一種對象構建的設計模式,它可以將複雜物件的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。
【2】簡單分析
我們先來看一下該設計模式的UML結構圖
是Strategy 模式的結構圖,讓我們可以進行更方便的描述:
-
為建立一個Product對象的各個組件指定抽象介面。
-
實現Builder的介面以構造和裝配該產品的各個組件。
-
定義並明確它所建立的表示。
-
提供一個檢索產品的介面
-
構造一個使用Builder介面的對象。
-
表示被構造的複雜物件。ConcreateBuilder建立該產品的內部表示並定義它的裝配過程。
在以下情況使用產生器模式:
-
包含定義組成組件的類,包括將這些組件裝配成最終產品的介面。
-
- 當建立複雜物件(這些對象內部構建間的建造順序通常是穩定的)的演算法應該獨立於該對象的組成部分以及它們的裝配方式時;
- 當構造過程必須允許被構造的對象有不同的表示時。
【3】如何用java語言來實現該模式
下面以一個簡單的例子來展示該模式,先看下代碼結構圖:
3.1 先建立一個Product類--產品類:
package com.andyidea.patterns.product;/** * Product--產品類 * @author Andy.Chen * */public class Pizza { private String dough; private String sauce; private String topping; public void setDough(String dough) {this.dough = dough;}public void setSauce(String sauce) {this.sauce = sauce;}public void setTopping(String topping) {this.topping = topping;}}
3.2 建立抽象建造者類:PizzaBuilder.java
package com.andyidea.patterns.builder;import com.andyidea.patterns.product.Pizza;/** * Builder類--抽象建造者類 * @author Andy.Chen * */public abstract class PizzaBuilder { protected Pizza pizza; public Pizza getPizza() { return pizza; } public void createNewPizzaProduct() { pizza = new Pizza(); } public abstract void buildDough(); public abstract void buildSauce(); public abstract void buildTopping();}
3.3 建立具體建造者類
HawaiianPizzaBuilder.java源碼:
package com.andyidea.patterns.concretebuilder;import com.andyidea.patterns.builder.PizzaBuilder;/** * ConcreteBuilder類--具體建造者類 * @author Andy.Chen * */public class HawaiianPizzaBuilder extends PizzaBuilder {@Overridepublic void buildDough() {System.out.println("Hawaiian-Dough");pizza.setDough("Hawaiian-Dough");}@Overridepublic void buildSauce() {System.out.println("Hawaiian-Sauce"); pizza.setSauce("Hawaiian-Sauce");}@Overridepublic void buildTopping() {System.out.println("Hawaiian-Topping"); pizza.setTopping("Hawaiian-Topping");}}
SpicyPizzaBuilder.java源碼:
package com.andyidea.patterns.concretebuilder;import com.andyidea.patterns.builder.PizzaBuilder;/** * ConcreteBuilder類--具體建造者類 * @author Andy.Chen * */public class SpicyPizzaBuilder extends PizzaBuilder {@Overridepublic void buildDough() {System.out.println("Spicy-Dough");pizza.setDough("Spicy-Dough");}@Overridepublic void buildSauce() {System.out.println("Spicy-Sauce");pizza.setSauce("Spicy-Sauce");}@Overridepublic void buildTopping() {System.out.println("Spicy-Topping");pizza.setTopping("Spicy-Topping");}}
3.4 建立指揮者(Director)類:Waiter.java
package com.andyidea.patterns.director;import com.andyidea.patterns.builder.PizzaBuilder;import com.andyidea.patterns.product.Pizza;/** * Director類--指揮者類 * @author Andy.Chen * */public class Waiter { private PizzaBuilder pizzaBuilder; public void setPizzaBuilder (PizzaBuilder pb) { pizzaBuilder = pb; }public Pizza getPizza() { return pizzaBuilder.getPizza(); } public void constructPizza() { pizzaBuilder.createNewPizzaProduct(); pizzaBuilder.buildDough(); pizzaBuilder.buildSauce(); pizzaBuilder.buildTopping();}}
3.5 測試類別:BuilderClient.java
package com.andyidea.patterns.client;import com.andyidea.patterns.builder.PizzaBuilder;import com.andyidea.patterns.concretebuilder.HawaiianPizzaBuilder;import com.andyidea.patterns.concretebuilder.SpicyPizzaBuilder;import com.andyidea.patterns.director.Waiter;import com.andyidea.patterns.product.Pizza;public class BuilderClient {public static void main(String[] args) {System.out.println("Welcome to Andy.Chen Blog!" +"\n" +"Builder Patterns." +"\n"); Waiter waiter = new Waiter(); PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder(); PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder(); System.out.println("------------HawaiianPizza------------"); waiter.setPizzaBuilder(hawaiian_pizzabuilder); waiter.constructPizza(); System.out.println("------------SpicyPizza------------"); waiter.setPizzaBuilder(spicy_pizzabuilder); waiter.constructPizza(); Pizza pizza = waiter.getPizza();}}
【4】程式運行結果:
Welcome to Andy.Chen Blog!Builder Patterns.------------HawaiianPizza------------Hawaiian-DoughHawaiian-SauceHawaiian-Topping------------SpicyPizza------------Spicy-DoughSpicy-SauceSpicy-Topping
通過上面我們可以看到:建造者模式的好處就是使得建造代碼與表示代碼分離,由於建造者隱藏了該產品是如何組裝的,所以若需要改變一個產品的內部表示,只需要再定義一個具體的建造者就可以了。