1. 程式人生 > >Java進階篇設計模式之三 ----- 建造者模式和原型模式

Java進階篇設計模式之三 ----- 建造者模式和原型模式

前言

上一篇中我們學習了工廠模式,介紹了簡單工廠模式、工廠方法和抽象工廠模式。本篇則介紹設計模式中屬於建立型模式的建造者模式和原型模式。

建造者模式

簡介

建造者模式是屬於建立型模式。建造者模式使用多個簡單的物件一步一步構建成一個複雜的物件。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
簡單的來說就是將一個複雜的東西抽離出來,對外提供一個簡單的呼叫,可以在同樣的構建過程建立不同的表示。和工廠模式很相似,不過相比而言更加註重元件的裝配。

這裡用一個示例來進行說明。
我們一天吃的食物有這些,煎餅、盒飯、拉麵、豆漿、牛奶和果汁。分為三餐、早餐、午餐和晚餐,餐點主要包含吃的(俗稱飯)和喝的(豆漿,果汁之類的),那麼我們可以把煎餅和豆漿作為早餐,盒飯和果汁作為午餐,這樣我們可以清楚的知道要吃早餐和午餐包含什麼食物。

首先我們定義一個食物類,有兩個屬性,吃的和喝的。

class Meal{
    private String food;
    private String drinks;
    
    public String getFood() {
        return food;
    }
    public void setFood(String food) {
        this.food = food;
    }
    
    public String getDrinks() {
        return drinks;
    }
    public void setDrinks(String drinks) {
        this.drinks = drinks;
    }
}

定義了食物時候,我們在定義一個食物的標準介面,一份食物包含什麼,其實也就是吃的和喝的。

interface IBuilderFood{
    void buildFood();
    void buildDrinks();
    Meal createMeal();
}

食物介面定義一個吃的和一個喝的元件,然後通過createMeal()方法返回我們需要的食物。
那麼現在我們便可以定義一份早餐和午餐。
程式碼示例:

class Breakfast implements IBuilderFood{
    Meal meal;

    public Breakfast(){
        meal=new Meal();
    }
    
    @Override
    public void buildFood() {
        meal.setFood("煎餅");
    }

    @Override
    public void buildDrinks() {
        meal.setDrinks("豆漿");   
    }
    
    @Override
    public Meal createMeal() {
        return meal;
    }
}

class Lunch implements IBuilderFood{
    Meal meal;

    public Lunch(){
        meal=new Meal();
    }
    
    @Override
    public void buildFood() {
        meal.setFood("盒飯");
    }

    @Override
    public void buildDrinks() {
        meal.setDrinks("果汁");   
    }
    
    @Override
    public Meal createMeal() {
        return meal;
    }
}

定義完之後,建造早餐和午餐的的過程已經完畢了。但是這並不是建造者模式,它有個核心的Director(導演者),它用來建立複雜物件的部分,對該部分進行完整的建立或者按照一定的規則進行建立。那麼這裡我們可以建立一個Director,用來建立一份餐點。至於建立的是什麼餐點,它不用知道,這一點由呼叫者來進行決定。

這裡我們就可以定義一個飯店,可以建立一份餐點,建立什麼餐點有顧客決定。
程式碼示例:

class FoodStore{
    public Meal createBreakfast(IBuilderFood bf){
        bf.buildDrinks();
        bf.buildFood();
        return bf.createMeal();
    }
}

建立完成這個Director之後,我們再來進行呼叫測試。

程式碼示例:


public class BuilderTest {

    public static void main(String[] args) {
        FoodStore foodStore=new FoodStore();
        Meal meal=foodStore.createBreakfast(new Breakfast());
        Meal meal2=foodStore.createBreakfast(new Lunch());
        System.out.println("小明早上吃的是:"+meal.getFood()+",喝的飲料是:"+meal.getDrinks());
        System.out.println("小明中午吃的是:"+meal2.getFood()+",喝的飲料是:"+meal2.getDrinks()); 
    }

}

輸出結果:

小明早上吃的是:煎餅,喝的飲料是:豆漿
小明中午吃的是:盒飯,喝的飲料是:果汁

簡單的介紹了下建造者模式的運作原理,可以概況為這4點:

  1. Builder:指定一個抽象的介面,規定該產品所需實現部件的建立,並不涉及具體的物件部件的建立。

  2. ConcreteBuilder:需實現Builder介面,並且針對不同的邏輯,進行不同方法的建立,最終提供該產品的例項。

  3. Director:用來建立複雜物件的部分,對該部分進行完整的建立或者按照一定的規則進行建立。

  4. Product:示被構造的複雜物件。

使用場景:
適用一些基本元件不便,但是組合經常變化的時候。比如超市促銷的大禮包。

優點:

  1. 建造者獨立,易擴充套件。
  2. 便於控制細節風險。

缺點

  1. 內部結構複雜,不易於理解。
  2. 產品直接需要有共同點,範圍有控制。

原型模式

原型模式(Prototype Pattern)是用於建立重複的物件,同時又能保證效能。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

一般來說我們在建立物件的時候是直接建立的,但是建立該物件的代價很大的時候,重複的二次建立就有些不划算,這時我們就可以使用原型模式。
打個比方,我們都發送過郵件,在節日的時候一般傳送的是祝福語句,在這些祝福語句中,一般除了名字不一樣之外,大部分都是一樣的。這時我們就可以利用該模式來進行相應出建立。

這裡還是用一個的簡單的示例來說明。
小明和小紅在同一天生日,然後我們需要給他們傳送郵件進行祝福,但是由於比較懶,祝福語除了名字之外都是一樣的。這時我們就可以先完成祝福語的編寫,然後克隆該祝福語,最後根據不同的名稱進行傳送。不過這裡就從簡了,只是簡單的列印下而已。

程式碼示例:

public class PrototypeTest {

    public static void main(String[] args) {
        Mail mail=new Mail();
        mail.setMsg("生日快樂!");
        Mail mail2=(Mail) mail.clone();
        mail.setName("小明");
        mail2.setName("小紅");
        System.out.println(mail.toString());
        System.out.println(mail2.toString());
    }
}

 class Mail implements Cloneable {
    private String name;
    private String msg;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }

    @Override
    public String toString() {
        return name + ":" + msg ;
    }
    
}

輸出結果:

小明:生日快樂!
小紅:生日快樂!

看完原型模式的建立,是不是感覺就是和Java中克隆即為類似呢?
實際上它的核心也就是克隆。
克隆有兩種,淺克隆和深克隆,本文主要介紹的是淺克隆。
淺克隆:

在淺克隆中,如果原型物件的成員變數是值型別,將複製一份給克隆物件;如果原型物件的成員變數是引用型別,則將引用物件的地址複製一份給克隆物件,也就是說原型物件和克隆物件的成員變數指向相同的記憶體地址。
簡單來說,在淺克隆中,當物件被複制時只複製它本身和其中包含的值型別的成員變數,而引用型別的成員物件並沒有複製。
實現Cloneable介面並重寫Object類中的clone()方法;

深克隆:

在深克隆中,無論原型物件的成員變數是值型別還是引用型別,都將複製一份給克隆物件,深克隆將原型物件的所有引用物件也複製一份給克隆物件。

簡單來說,在深克隆中,除了物件本身被複制外,物件所包含的所有成員變數也將複製。
實現Serializable介面,通過物件的序列化和反序列化實現克隆,可以實現真正的深度克隆。

使用場景:

  1. 類初始化的時候需要消耗大量資源的時候;
  2. 獲取資料庫連線繁瑣的時候;
  3. 一個物件,有很多個修改者的時候;

優點:
1.可以提升效能;

缺點:
1.因為必須實現Cloneable 介面,所以用起來可能不太方便。

其它

音樂推薦

原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力!
版權宣告:
作者:虛無境
部落格園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm    
個人部落格出處:http://www.panchengming.com
原創不易,轉載請標明出處,謝謝!

相關推薦

Java設計模式 ----- 建造模式原型模式

前言 在上一篇中我們學習了工廠模式,介紹了簡單工廠模式、工廠方法和抽象工廠模式。本篇則介紹設計模式中屬於建立型模式的建造者模式和原型模式。 建造者模式 簡介 建造者模式是屬於建立型模式。建造者模式使用多個簡單的物件一步一步構建成一個複雜的物件。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式

Java設計模式二 ----- 工廠模式

class computer 社會 進階 輕松 override out 是否 return 前言 在上一篇中我們學習了單例模式,介紹了單例模式創建的幾種方法以及最優的方法。本篇則介紹設計模式中的工廠模式,主要分為簡單工廠模式、工廠方法和抽象工廠模式。 簡單工廠模式 簡單

Java設計模式四 -----適配器模式橋接模式

原則 pub 是我 protect 接口 logs 將不 多說 外鏈 前言 在上一篇中我們學習了創建型模式的建造者模式和原型模式。本篇則來學習下結構型模式的適配器模式和橋接模式。 適配器模式 簡介 適配器模式是作為兩個不兼容的接口之間的橋梁。這種類型的設計模式屬於結構型模

Java設計模式五-----外觀模式裝飾器模式

和我 logs 適配器模式 del xtra implement () 實例化 網絡遊戲 前言 在上一篇中我們學習了結構型模式的適配器模式和橋接模式。本篇則來學習下結構型模式的外觀模式和裝飾器模式。 外觀模式 簡介 外觀模式隱藏系統的復雜性,並向客戶端提供了一個客戶端可以

Java設計模式六 ----- 組合模式過濾器模式

對組 www. 希望 als oid block 個人 定義 lsi 前言 在上一篇中我們學習了結構型模式的外觀模式和裝飾器模式。本篇則來學習下組合模式和過濾器模式。 組合模式 簡介 組合模式是用於把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表

Java設計模式八 ----- 責任鏈模式命令模式

如果能 clean branch pcm tle 開始 類型 mar www 前言 在上一篇中我們學習了結構型模式的享元模式和代理模式。本篇則來學習下行為型模式的兩個模式, 責任鏈模式(Chain of Responsibility Pattern)和命令模式(Comman

Java設計模式九----- 解釋器模式叠代器模式

簡單 目的 java進階 使用 記錄 ace 客戶端 -- pro 前言 在上一篇中我們學習了行為型模式的責任鏈模式(Chain of Responsibility Pattern)和命令模式(Command Pattern)。本篇則來學習下行為型模式的兩個模式, 解釋器模

Java設計模式十 ---- 訪問者模式中介模式

前言 在上一篇中我們學習了結構型模式的直譯器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern)。本篇則來學習下行為型模式的兩個模式,訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。 訪問者模式 簡介 訪問者

Java設計模式十一 ---- 策略模式模板方法模式

前言 在上一篇中我們學習了行為型模式的訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。本篇則來學習下行為型模式的兩個模式,策略模式(Strategy Pattern)和模板模式(Mediator Pattern)。 策略模式 簡介 策略模式(Stra

Java設計模式十二 ---- 備忘錄模式狀態模式

前言 在上一篇中我們學習了行為型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern)。本篇則來學習下行為型模式的兩個模式,備忘錄模式(Memento Pattern)和狀態模式(Memento Pattern)。 備忘錄模式 簡介 備忘錄模式(Meme

Java設計模式七 ----- 享元模式代理模式

前言 在上一篇中我們學習了結構型模式的組合模式和過濾器模式。本篇則來學習下結構型模式最後的兩個模式, 享元模式和代理模式。 享元模式 簡介 享元模式主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。 用通俗的話來

Java 設計模式十四 ----- 總結

前言 本篇是講述之前學習設計模式的一個總結篇,其目的是為了對這些設計模式的進行一個提煉總結,能夠通過檢視看此篇就可以理解一些設計模式的核心思想。 設計模式簡介 什麼是設計模式 設計模式是一套被反覆使用的、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。 為什麼使用設計模式 使用

Java設計模式九----- 直譯器模式迭代器模式

前言 在上一篇中我們學習了行為型模式的責任鏈模式(Chain of Responsibility Pattern)和命令模式(Command Pattern)。本篇則來學習下行為型模式的兩個模式, 直譯器模式(Interpreter Pattern)和迭代器模式

Java設計模式四 -----介面卡模式橋接模式

前言 在上一篇中我們學習了建立型模式的建造者模式和原型模式。本篇則來學習下結構型模式的介面卡模式和橋接模式。 介面卡模式 簡介 介面卡模式是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。 簡單的來說就是通過某個介面將不相容的兩個類進行相容,俗稱轉換器。 生活

Java設計模式之一 ----- 單例模式

前言 在剛學程式設計沒多久就聽說過設計模式的大名,不過由於當時還是個徹徹底底的菜鳥,並沒有去觸碰。直到在開始工作中對簡單的業務程式碼較為熟悉之後,才正式的接觸設計模式。當時最早接觸的設計模式是工廠模式,不過本文講的是單例模式,這裡就留著下篇文章中在講解。至於為什麼先講解單例模式? 那是因為單例模式是設計模式中

Java十五 ----- JDK1.8的Lambda、Stream日期的使用詳解(很詳細)

前言 本篇主要講述是Java中JDK1.8的一些新語法特性使用,主要是Lambda、Stream和LocalDate日期的一些使用講解。 Lambda Lambda介紹 Lambda 表示式(lambda expression)是一個匿名函式,Lambda表示式基於數學中的λ演算得名,直接對應於

Java(五)——Java的I/O技術

  程式中,為了永久的儲存建立的資料,需要將其儲存在磁碟檔案中,以便在其它程式中使用它們。Java的I/O技術可以將資料儲存到文字檔案、二進位制檔案甚至是ZIP壓縮檔案中,以達到永久性儲存資料的要求。   本篇我們要介紹的內容就是Java的I/O技術,即輸入/輸出。 一、輸入/輸出流   流是一組有序的資料序

:優先順序佇列PriorityBlockingQueue(十五)

今天我們來講下PriorityBlockingQueue這個佇列,它是一個優先順序佇列,什麼是優先順序呢?意思就是我們可以定義佇列中哪個元素可以先被取出! 它與前面介紹的LinkedBlockingQueue不同的地方就是,它是可以定義優先順序的!且入隊的元素必須實現Com

淺析設計模式(七)——創建型模式Builder(建造模式)

main方法 ref 內部 spa implement line pat 接口 及其 建造者模式Builder 本文的內容: 一、建造者模式的定義 二、建造者模式的參與者及其角色 三、建造者模式的類圖 四、建造者模式的示例 五、參考 一、建造者模式的定義    將一個復

SODBASE CEP學習(六):實現反壓流限速

前面文章介紹過流資料輸入速率要和處理能力相匹配,短時資料爆發由內部緩衝佇列來緩衝。如果確實存在某個時間點持續資料爆發,可以考慮採取反壓限流的方法。 1. 示例操作步驟 (1)下載SODBASE Studio2.0.22(sp1)以上版本,解壓,開啟configuration