當前位置:
首頁 > 知識 > 每日一博丨淺談設計模式之建造者模式

每日一博丨淺談設計模式之建造者模式

每日一博丨淺談設計模式之建造者模式

歡迎下載開源中國APP獲取更多優質文章

介紹

意圖:將一個複雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。

主要解決:主要解決在軟體系統中,有時候面臨著"一個複雜對象"的創建工作,其通常由各個部分的子對象用一定的演算法構成;由於需求的變化,這個複雜對象的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法卻相對穩定。

何時使用:一些基本部件不會變,而其組合經常變化的時候。

如何解決:將變與不變分離開。

關鍵代碼:建造者:創建和提供實例,導演:管理建造出來的實例的依賴關係。

應用實例: 1、去肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。 2、JAVA 中的 StringBuilder。3、SQL中的PreparedStatement

優點: 1、建造者獨立,易擴展。 2、便於控制細節風險。

缺點: 1、產品必須有共同點,範圍有限制。 2、如內部變化複雜,會有很多的建造類。

使用場景: 1、需要生成的對象具有複雜的內部結構。 2、需要生成的對象內部屬性本身相互依賴。

注意事項:與工廠模式的區別是:建造者模式更加關注與零件裝配的順序。

實現

我們假設一個快餐店的商業案例,去肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。其中,一個典型的套餐可以是一個漢堡(Burger)和一杯冷飲(Cold drink)。漢堡(Burger)可以是素食漢堡(Veg Burger)或雞肉漢堡(Chicken Burger),它們是包在紙盒中。冷飲(Cold drink)可以是可口可樂(coke)或百事可樂(pepsi),它們是裝在瓶子中。

我們將創建一個表示食物條目(比如漢堡和冷飲)的 Item 介面和實現 Item 介面的實體類,以及一個表示食物包裝的 Packing 介面和實現 Packing 介面的實體類,漢堡是包在紙盒中,冷飲是裝在瓶子中。

然後我們創建一個 Meal 類,帶有 Item 的 ArrayList 和一個通過結合 Item 來創建不同類型的 Meal 對象的 MealBuilder。BuilderPatternDemo,我們的演示類使用 MealBuilder 來創建一個 Meal。

代碼示例:

1、創建一個表示食物條目和食物包裝的介面 Item、Packing

package builder.item.service;

import builder.pack.service.Packing;

/**

* 食物條目介面

* @author lihaoshan

* @date 2018-06-27

* */

public interface Item {

/**名字*/

public String name();

/**價格*/

public Double price();

public Packing packing();

}

package builder.pack.service;

/**

* 包裝介面

* @author lihaoshan

* @date 2018-06-27

* */

public interface Packing {

/**包裝*/

public String pack();

}

2、創建 Packing 介面的實現類

package builder.pack.impl;

import builder.pack.service.Packing;

/**

* 包裝介面實現類【瓶裝】

* @author lihaoshan

* @date 2018-06-28

* */

public class Bottle implements Packing{

@Override

public String pack(){

return "瓶裝";

}

}

package builder.pack.impl;

import builder.pack.service.Packing;

/**

* 包裝介面實現類【紙盒包裝】

* @author lihaoshan

* @date 2018-06-28

* */

public class Wrapper implements Packing {

@Override

public String pack(){

return "紙盒包裝";

}

}

3、創建實現 Item 介面的抽象類

package builder.item.impl;

import builder.pack.impl.Wrapper;

import builder.item.service.Item;

import builder.pack.service.Packing;

/**

* 食物條目實現抽象類【漢堡】

* @author lihaoshan

* @date 2018-06-28

* */

public abstract class Burger implements Item{

@Override

public Packing packing(){

return new Wrapper();

}

@Override

public abstract Double price();

}

package builder.item.impl;

import builder.pack.impl.Bottle;

import builder.item.service.Item;

import builder.pack.service.Packing;

/**

* 食物條目實現抽象類【可樂】

* @author lihaoshan

* @date 2018-06-28

* */

public abstract class ColdDrink implements Item{

@Override

public Packing packing(){

return new Bottle();

}

@Override

public abstract Double price();

}

4、創建擴展了 Burger 和 ColdDrink 的實體類

package builder.po;

import builder.item.impl.Burger;

/**

* 擴展Burger的實體類【雞肉漢堡】

*

* @author lihaoshan

* @date 2018-06-28

* */

public class ChickenBurger extends Burger{

@Override

public Double price(){

return 30.0;

}

@Override

public String name(){

return "雞肉漢堡";

}

}

package builder.po;

import builder.item.impl.ColdDrink;

/**

* 擴展ColdDrink的實體類【可口可樂】

*

* @author lihaoshan

* @date 2018-06-28

* */

public class Coke extends ColdDrink{

@Override

public Double price(){

return 10.0;

}

@Override

public String name(){

return "可口可樂";

}

}

package builder.po;

import builder.item.impl.ColdDrink;

/**

* 擴展ColdDrink的實體類【百事可樂】

*

* @author lihaoshan

* @date 2018-06-28

* */

public class Pepsi extends ColdDrink{

@Override

public Double price(){

return 12.0;

}

@Override

public String name(){

return "百事可樂";

}

}

package builder.po;

import builder.item.impl.Burger;

/**

* 擴展Burger的實體類【素食漢堡】

*

* @author lihaoshan

* @date 2018-06-28

* */

public class VegBurger extends Burger {

@Override

public Double price() {

return 25.0;

}

@Override

public String name() {

return "素食漢堡";

}

}

5、創建點餐類 Meal,帶有食物條目對象

package builder;

import builder.item.service.Item;

import java.util.ArrayList;

import java.util.List;

/**

* 點餐類,帶有食物條目對象

*

* @author lihaoshan

* @date 2018-06-28

* */

public class Meal {

/**食物條目對象*/

private List<Item> items = new ArrayList<Item>();

/**

* 點餐方法

*

* @param item

* */

public void addItem(Item item){

items.add(item);

}

/**

* 點餐費用

*

* */

public Double getCost(){

Double cost = 0.0;

for (Item item : items) {

cost +=item.price();

}

return cost;

}

/**

* 展示食物條目

*

* */

public void showItems(){

System.out.println("菜單 包裝 費用
");

for (Item item : items) {

System.out.print(item.name()+" "+item.packing().pack()+" "+item.price()+"
");

}

}

}

6、創建一個點餐服務類 MealBuilder

package builder;

import builder.po.ChickenBurger;

import builder.po.Coke;

import builder.po.Pepsi;

import builder.po.VegBurger;

/**

* 點餐服務類

* @author lihaoshan

* @date 2018-06-28

* */

public class MealBuilder {

/**

* 素食套餐

* */

public Meal prepareVegMeal(){

Meal meal = new Meal();

meal.addItem(new VegBurger());

meal.addItem(new Coke());

return meal;

}

/**

* 非素食套餐

* */

public Meal prepareNonVegMeal(){

Meal meal = new Meal();

meal.addItem(new ChickenBurger());

meal.addItem(new Pepsi());

return meal;

}

}

7、創建一個測試類 BuiderPatternDemo

package builder;

import org.junit.Test;

/**

* 建造者模式 測試類

* @author lihaoshan

* @date 2018-06-28

* */

public class BuilderPatternDemo {

@Test

public void test(){

MealBuilder mealBuilder = new MealBuilder();

Meal vegMeal = mealBuilder.prepareVegMeal();

System.out.println("***************素食餐***************");

vegMeal.showItems();

System.out.println("總合計: " +vegMeal.getCost());

Meal nonVegMeal = mealBuilder.prepareNonVegMeal();

System.out.println("

***************非素食餐***************");

nonVegMeal.showItems();

System.out.println("總合計: " +nonVegMeal.getCost());

}

}

8、運行結果如下:

每日一博丨淺談設計模式之建造者模式

博客作者(WeChat):佛系程序猿

每日一博欄目,每日為你推薦優秀博主的優質技術文章。同時歡迎用戶投稿,文章一旦被官方賬號收錄,我們會在網站首頁等位置進行推薦哦。點擊「了解更多」,閱讀原文章,獲取源碼地址。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 OSC開源社區 的精彩文章:

開源項目丨基於 Spring Boot 的分散式和服務化解決方案 Roses
RSS 之父 Winer 炮轟 Google 反客為主強推 HTTPS

TAG:OSC開源社區 |