搜尋
首頁Javajava教程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 接口,所以用起来可能不太方便。

相关推荐:

Java设计模式中工厂模式的介绍(代码示例)

Java设计模式是什么?Java设计模式中单例模式的介绍

以上是Java設計模式中建造者模式和原型模式的介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。