建造者模式學習

建造者模式(Builder Pattern)屬於建立型模式的一種,將多個簡單對象構建成一個複雜的對象,構建過程抽象化,不一樣實現方法能夠構造出不一樣表現(屬性)的對象,還提供了一種更加優雅構建對象的方式...git

概述

有時候構建一個複雜的對象,須要通過好幾步的處理,好比經常使用的StringBuffer、StringBuilder、以及Swagger(一種接口文檔),都是以這種模式構建對象的程序員

優勢github

  • 建造者模式比較獨立,將對象自己與構建過程解耦
  • 精準控制構建出的對象和內容,構造層和顯示層是分離的
  • 寫法上更加優雅

缺點函數

  • 範圍受限,不適合差別較大的對象
  • 內部複雜多變,構造類相對會多

適用場景ui

  • 構建具備共同特性的複雜對象

相關模式this

抽象工廠模式與建造者模式類似,由於它也能夠建立複雜對象。主要的區別是建造者模式着重於一步步得構造出複雜對象。而抽象工廠模式着重於多個系列的產品對象(簡單的或是複雜的)。建造者是在最後的一步返回對象,而對於抽象工廠來講,對象是當即返回的。插件

案例

傳統方式code

public class Summoner {

    private String name;  
    private String type;  
    private String innate;

    public Summoner(String name, String type, String innate) {  
        this.name = name;  
        this.type = type;  
        this.innate = innate;  
    }  
}

簡單的對象咱們可使用下面這種方式,由於屬性較少這種方式還看的,但不幸的是若是要增長字段或咱們還須要去擴展構造方法,且可讀性很差,相同類型的狀況下在必定程度上混淆視聽了對象

Summoner s1 = new Summoner("德瑪","戰士","戰爭雷霆");

爲何不調用無參數的構造函數,經過setter方法來減輕問題。接口

解答: 若是程序員忘記調用一個特定的setter方法會發生什麼?咱們可能獲得的是一個部分初始化的對象,並且編譯器也不會檢測出任何問題。

  • 構造函數參數太多
  • 錯誤的對象狀態

使用模式

在咱們的示例中,改造下召喚師類

public class Summoner {

    private String name;  
    private String type;  
    private String innate;

    private Summoner(Builder builder) {  
        this.name = builder.name;  
        this.type = builder.type;  
        this.innate = builder.innate;  
    }

    protected static class Builder {  
        private String name;  
        private String type;  
        private String innate;

        protected Builder name(String name) {  
            this.name = name;  
            return this;  
        }

        protected Builder type(String type) {  
            this.type = type;  
            return this;  
        }

        protected Builder innate(String innate) {  
            this.innate = innate;  
            return this;  
        }  
        protected Summoner build() {  
            return new Summoner(this);  
        }  
    }  
}

public class BuilderDemo {

    public static void main(String\[\] args) {  
        Summoner monkey = new Summoner.Builder().name("齊天大聖 - 孫悟空").type("上單 - AD").innate("基石天賦 - 戰爭雷霆").build();  
        System.out.println(monkey.toString());

        Summoner mouse = new Summoner.Builder().name("瘟疫之源 - 圖奇").type("下路 - ADC").innate("基石天賦 - 戰陣熱誠").build();  
        System.out.println(mouse.toString());

        Summoner diann = new Summoner.Builder().name("皎月女神 - 戴安娜").type("中單 - AP").build();  
        System.out.println(diann.toString());  
    }  
}

建造者模式讓咱們寫的代碼更具可讀性,可理解爲創建複雜的物體。它每每是實現一個連貫的操做,從而更加直觀,此處因爲類型較爲單一差距不大,但遇到複雜對象構建差距就立竿見影了

Summoner{name='齊天大聖 - 孫悟空', type='上單 - AD', innate='基石天賦 - 戰爭雷霆'}  
Summoner{name='瘟疫之源 - 圖奇', type='下路 - ADC', innate='基石天賦 - 戰陣熱誠'}  
Summoner{name='皎月女神 - 戴安娜', type='中單 - AP', innate='null'}

總結

咱們經過一個簡單的代碼例子開始,慢慢變得複雜。而後使用Builder模式來解決咱們發現的問題。

若是你發現本身在一個狀況下,你不斷添加新參數的構造函數,使得代碼變得容易出錯,很難讀,也許能夠考慮使用一個Builder重構你的代碼。

推薦

全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter4/battcn-builder

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息