- Android設計模式與最佳實踐
- (英)凱爾·繆
- 1110字
- 2021-02-07 09:26:40
2.5 應用建造者模式
建造者設計模式是最有用的創建型模式之一,因為它將較小的對象構建成較大的對象。這正是我們想要做的——從原料列表中構建出一個三明治對象。建造者模式還有一個更大的優勢,就是以后可以很容易地增加可選功能。和以前一樣,先要創建一個稱為Ingredient的接口,并用它來表示Bread和Filling。這一次需要將熱值表示為整數類型,因為我們需要計算成品三明治的總熱量。
打開一個Android Studio項目或啟動一個新項目,然后按照以下步驟創建一個基本的三明治建造者模式。
(1)創建一個名為Ingredient.java的新接口,用如下代碼實現:
public interface Ingredient { String name(); int calories(); }
(2)創建一個名為Bread的抽象類:
public abstract class Bread implements Ingredient { @Override public abstract String name(); @Override public abstract int calories(); }
(3)創建一個一樣的抽象類——Filling。
(4)接下來,創建Bread的具體類: public class Bagel extends Bread { @Override public String name() { return "Bagel"; } @Override public int calories() { return 250; } }
(5)對Filling類進行相同的操作。每種類型定義兩個類,已經足夠達到演示的目的:
public class SmokedSalmon extends Filling { @Override public String name() { return "Smoked salmon"; } @Override public int calories() { return 400; } }
(6)現在可以創建Sandwich類:
public class Sandwich { private static final String DEBUG_TAG = "tag"; //創建持有原料的列表 private List<Ingredient> ingredients = new ArrayList<Ingredient>(); //計算總熱值 public void getCalories() { int c = 0; for (Ingredient i : ingredients) { c+= i.calories(); } Log.d(DEBUG_TAG, "Total calories : "+c+" kcal"); } //添加原料 public void addIngredient(Ingredient ingredient) { ingredients.add(ingredient); } //輸出原料 public void getSandwich() { for (Ingredient i : ingredients) { Log.d(DEBUG_TAG, i.name()+" : "+i.calories()+" kcal"); } } }
(7)最后,創建SandwichBuilder類:
public class SandwichBuilder { //現成的三明治 public static Sandwich readyMade() { Sandwich sandwich = new Sandwich(); sandwich.addIngredient(new Bagel()); sandwich.addIngredient(new SmokedSalmon()); sandwich.addIngredient(new CreamCheese()); return sandwich; } //定制三明治 public static Sandwich build(Sandwich s, Ingredient i) { s.addIngredient(i); return s; } }
建造者設計模式已經完成,至少目前如此,如圖2-12所示。

圖2-12
這里,我們為建造者提供了兩個功能:返回現成的三明治和用戶定制的三明治。現在還沒有可使用的界面,但是我們可以通過客戶端代碼模擬用戶的選擇。
我們還將輸出的職責委托給了Sandwich類,這通常是一個明智的選擇,因為這有助于保持客戶端代碼整潔和清晰,正如下邊的代碼所示:
//創建一個定制的三明治 SandwichBuilder builder = new SandwichBuilder(); Sandwich custom = new Sandwich(); //模擬用戶的選擇 custom = builder.build(custom, new Bun()); custom = builder.build(custom, new CreamCheese()); Log.d(DEBUG_TAG, "CUSTOMIZED"); custom.getSandwich(); custom.getCalories(); //創建一個現成的三明治 Sandwich offTheShelf = SandwichBuilder.readyMade(); Log.d(DEBUG_TAG, "READY MADE"); offTheShelf.getSandwich(); offTheShelf.getCalories();
代碼將產生如下輸出:
D/tag: CUSTOMIZED D/tag: Bun : 150 kcal D/tag: Cream cheese : 350 kcal D/tag: Total calories : 500 kcal D/tag: READY MADE D/tag: Bagel : 250 kcal D/tag: Smoked salmon : 400 kcal D/tag: Cream cheese : 350 kcal D/tag: Total calories : 1000 kcal
建造者最大的優點之一是非常容易添加、刪除和修改具體類,甚至在修改接口或抽象類時,也不需要修改客戶端源代碼。這使得建造者模式成為最強大的模式之一,它可以在許多場景下使用。這并不是說,它總是比工廠模式更好。對于簡單的對象,工廠模式通常是最好的選擇。當然,模式存在于不同的尺度上,工廠模式嵌套在建造者模式中并不罕見,反之亦然。
推薦閱讀
- 從零開始:數字圖像處理的編程基礎與應用
- Practical DevOps
- Learning Network Forensics
- 快人一步:系統性能提高之道
- RSpec Essentials
- Python Deep Learning
- 交互設計師成長手冊:從零開始學交互
- Python數據可視化之matplotlib實踐
- Oracle Database 12c DBA官方手冊(第8版)
- Implementing DevOps with Ansible 2
- Java 8實戰
- Full Stack Development with JHipster
- XML實用教程
- 數字化中臺
- Learning ArcGIS Runtime SDK for .NET