溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java設(shè)計模式中生成器模式是什么

發(fā)布時間:2021-11-17 10:35:19 來源:億速云 閱讀:117 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要介紹了Java設(shè)計模式中生成器模式是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

簡介

生成器模式(Builder Pattern)隸屬與設(shè)計模式中的創(chuàng)建者模式,主要目的是對復雜對象的構(gòu)建步驟進行拆解。

定義

生成器模式:又名建造者模式,是將復雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現(xiàn)方法可以構(gòu)造出不同表現(xiàn)(屬性)的對象。

這個定義讀起來完全不知道是啥子回事,通俗的來講就是原來一個要構(gòu)造一個完整的類,需要先 new 出這個對象來,然后對象有什么屬性也需要一步步構(gòu)造出來,然后再 set 到對象中,從 newset 的這個過程就叫對象的建造過程,生成器模式就是將這個建造過程和后續(xù)對象的使用分離開,使得對象的建造過程可復用,建造過程也更加清晰。

角色

生成器模式從有四種角色,分別是被構(gòu)造的復雜對象Product,抽象建造接口 Builder,具體建造實現(xiàn) ConcreteBuilder 和指導構(gòu)建過程的 Director。

這里說明一下指導構(gòu)建過程的 Director, 它在正常的生成器模式里是負責組裝 Builder 提供的各個部件成為 Product 的,與工廠的角色類似,但是很多時候我們并不定義這個指導者,而是由用戶來擔當這個角色,也就是由用戶來自行決定創(chuàng)建過程。

模式說明

組裝車、電腦這種復雜對象在很多時候是適合生成器模式的,我們這里用上節(jié)抽象工廠模式中提到的編輯器的主題來作說明。

主題通常包含一系列的復雜對象,像字體,背景,動畫,菜單選項等等,其中的每一項都很復雜,復雜到也可以使用生成器模式,這里簡單起見,我們就以幾個屬性來代替。

//產(chǎn)品 主題對象
public class Theme {
    private Font font;
    private Animation animation;
    private Menu menu;
    
    //setter getter 方法
    //...
}

不使用生成器模式,我們要構(gòu)造主題對象,需要代碼里寫死字體,動畫等的這些項,如下:

public class Client {
    public static void main(String[] args) {
        Theme theme = new Theme();
        
        Font font = new Font();
        //... font settings
        
        Animation = new Animation();
        //... animation settings
        
        Menu menu = new Menu();
        //... menu settings
        
        theme.setFont(font);
        theme.setAnimation(animation);
        theme.setMenu(menu);
        
        // 系統(tǒng)切換主題
        Editor.changeTheme(theme);
    }
}

可以看到用戶為了生成主題這個對象需要去了解字體,動畫,甚至是菜單設(shè)置這一類的額外工作,根據(jù)迪米特法則,用戶只需了解自己關(guān)心的知識,在這里,最核心的就是主題對象,其余的都是系統(tǒng)需要屏蔽的細節(jié)。

接下來我們使用生成器模式來生成這個復雜對象, 首先是抽象生成接口和具體的生成實現(xiàn)

//builder接口,一般是直接放在 Product 類里面作為靜態(tài)類
public interface ThemeBuilder {
    public ThemeBuilder makeTheme();
    public Theme build();
    public ThemeBuilder buildFont();
    public ThemeBuilder buildAnimation();
    public ThemeBuilder buildMenu();
    
    // other build part
}

public class DefaultThemeBuilder {
    private Theme theme;
    public ThemeBuilder makeTheme() {
        this.theme = new Theme();
    }
    public Theme build() {
        return theme;
    }
    public ThemeBuilder buildFont() {
        Font font = new Font();
        // font settings
        
        theme.setFont(font);
        return this;
    }
    public ThemeBuilder buildAnimation() {
        Animation animation = new Animation();
        //animation settings
        
        theme.setAnimation(animation);
        return this;
    }
    public ThemeBuilder buildMenu() {
        Menu menu = new Menu();
        // menu set
        
        theme.setMenu(menu);
        
        return this;
    }
}

我們將組成主題的組成部分分離開來,使用方就不需要關(guān)心具體每個部分的實現(xiàn)細節(jié)如何,只需要使用生成器提供的每部分的build 方法即可。

public class Client {
    public static void main(String[] args) {
        ThemeBuilder builder = new DefaultThemeBuilder();
        
        builder.makeTheme()
            .buildFont()
            .buildAnimation()
            .buildMenu();
        
        Theme theme = builder.build();
        
        // 系統(tǒng)切換主題
        Editor.changeTheme(theme);
    }
}

當用戶需要使用另一個主題,只要替換 DefaultThemeBuilder 為另一個 Builder 對象即可,可以做到運行時替換。

但是還存在一個問題,即主題的構(gòu)造流程一般是一致的,也就是說每次要構(gòu)建一個主題對象出來,用戶都得從 make 到 build 都調(diào)用一遍,針對這種情況,我們可以請出 Director 對象來幫助我們封裝統(tǒng)一的構(gòu)造過程。

public class ThemeDirector {
    private ThemeBuilder builder;
    
    public ThemeDirector(ThemeBuilder builder) {
        this.builder = builder;
    }
    
    public void construct() {
        builder.makeTheme()
            .buildFont()
            .buildAnimation()
            .buildMenu();
    }
}

public class Client {
    public static void main(String[] args) {
        ThemeBuilder builder = new DefaultThemeBuilder();
        
        ThemeDirector director = new ThemeDirector(builder);
        director.construct();
        
        Theme theme = builder.build();
        
        // 系統(tǒng)切換主題
        Editor.changeTheme(theme);
    }
}

Director 對象就跟工廠方法類似,是封裝了 Theme 這個復雜對象的構(gòu)建流程,不同的是 Director 是與 Builder 共同努力的,Builder 負責各個部分的構(gòu)建,Director 負責將各個部分組裝到產(chǎn)品中,而工廠方法則是把所有的細節(jié)都整合到自己的方法中來。

使用場景

  1. 當創(chuàng)建復雜對象的算法應該獨立于該對象的組成部分以及它們的裝配方式時;

  2. 當構(gòu)造過程必須允許被構(gòu)造的對象有不同的表示時。

優(yōu)缺點

優(yōu)點:

  1. 生成器模式最核心的就是分離其構(gòu)造過程和組成部分,實現(xiàn)兩者的松耦合

  2. 細節(jié)隱藏,產(chǎn)品的組成部分的構(gòu)建和產(chǎn)品的構(gòu)建分別由 Builder 和 Director 來負責,用戶只需要使用兩者就可以生成最終的產(chǎn)品

  3. 更好的復用,產(chǎn)品的構(gòu)建流程可以復用,組成部分也可以復用。

缺點:

  1. 更復雜,理解難度更高

  2. 類增多

最佳實踐

  1. 生成器模式適合于創(chuàng)建復雜對象,可以看到和工廠方法不同的地方在于生成器模式其實分了兩層,分別是構(gòu)建流程和組成對象的各個部分,以及兩層之間的橋梁裝配方式。因此使用哪種創(chuàng)建型模式取決于你對當前場景的分析

  2. 正常生成器模式中存在 Director 對象,用于指導構(gòu)建流程,實際開發(fā)中沒怎么見過 Director 對象,一般是由使用方來做裝配。

  3. 如果生成器組成的每部分是字符串或簡單對象時,Builder 可以直接實現(xiàn)為靜態(tài)內(nèi)部類,然后由用戶去決定如何裝配,這是更常見的一種使用方法。Java 中的 StringBuilder 就是一個沒有 Director 對象的生成器模式。

public class Theme {
    private String button;
    private String color;
    private String background;
    
    public Theme(Builder builder) {
        this.button = builder.getButton();
        this.color = builder.getColor();
        this.background = builder.getBackground();
    }
    //getter setter
    
    public static class Builder {
        private String button;
        private String color;
        private String background;
        public Builder() {
            
        }
        
        public Builder button(String button) {
            this.button = button;
            return this;
        }
        public Builder color(String color) {
            this.color = color;
            return this;
        }
        public Builder background(String background) {
            this.background = background;
            return this;
        }
        
        public Theme build() {
            return new Theme(this);
        }
    }
}

用戶直接使用Builder 來自行裝配

public class Client {
    public static void main(String[] args) {
        Theme.Builder builder = new Theme.Builder();
        
        Theme theme = builder.button("button")
                .color("white")
                .background("black")
                .build();
        
        // 系統(tǒng)切換主題
        Editor.changeTheme(theme);
    }
}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java設(shè)計模式中生成器模式是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI