Builder模式總結

來源:互聯網
上載者:User
模式動機

無論是在現實世界中還是在軟體系統中,都存在一些複雜的對象,它們擁有多個組成部分,如汽車,它包括車輪、方向盤、發動機等各種組件。而對於大多數使用者而言,無須知道這些組件的裝配細節,也幾乎不會使用單獨某個組件,而是使用一輛完整的汽車,可以通過建造者模式對其進行設計與描述,建造者模式可以將組件和其組裝過程分開,一步一步建立一個複雜的對象。使用者只需要指定複雜物件的類型就可以得到該對象,而無須知道其內部的具體構造細節。

在軟體開發中,也存在大量類似汽車一樣的複雜物件,它們擁有一系列成員屬性,這些成員屬性中有些是參考型別的成員對象。而且在這些複雜物件中,還可能存在一些限制條件,如某些屬性沒有賦值則複雜物件不能作為一個完整的產品使用;有些屬性的賦值必須按照某個順序,一個屬性沒有賦值之前,另一個屬性可能無法賦值等。

複雜物件相當於一輛有待建造的汽車,而對象的屬性相當於汽車的組件,建造產品的過程就相當於組合組件的過程。由於組合組件的過程很複雜,因此,這些組件的組合過程往往被“外部化”到一個稱作建造者的對象裡,建造者返還給用戶端的是一個已經建造完畢的完整產品對象,而使用者無須關心該對象所包含的屬性以及它們的組裝方式,這就是建造者模式的模式動機。 模式定義

造者模式(Builder Pattern):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

建造者模式是一步一步建立一個複雜的對象,它允許使用者只通過指定複雜物件的類型和內容就可以構建它們,使用者不需要知道內部的具體構建細節。建造者模式屬於對象建立型模式。根據中文翻譯的不同,建造者模式又可以稱為產生器模式。 樣本

在Effective Java第二版中,Josh Bloch在第二章中就提到使用Builder模式處理需要很多參數的建構函式。他不僅展示了Builder的使用,也描述了相這種方法相對使用帶很多參數的建構函式帶來的好處。需要指出的是Josh Bloch已經在他的書本貫穿了這一思想。 標準Builder

Person.java

package com.ricky.builder.ch1;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 16:39 */public class Person {    private final String firstName;    private final String lastName;    private final String middleName;    private final int age;    private final String street;    private final String district;    private final String city;    private final String province;    private final boolean isFemale;    private final boolean isEmployed;    public Person(String firstName, String lastName, String middleName, int age, String street,                  String district, String city, String province, boolean isFemale, boolean isEmployed) {        this.firstName = firstName;        this.lastName = lastName;        this.middleName = middleName;        this.age = age;        this.street = street;        this.district = district;        this.city = city;        this.province = province;        this.isFemale = isFemale;        this.isEmployed = isEmployed;    }    @Override    public String toString() {        return "Person{" +                "firstName='" + firstName + '\'' +                ", lastName='" + lastName + '\'' +                ", middleName='" + middleName + '\'' +                ", age=" + age +                ", street='" + street + '\'' +                ", district='" + district + '\'' +                ", city='" + city + '\'' +                ", province='" + province + '\'' +                ", isFemale=" + isFemale +                ", isEmployed=" + isEmployed +                '}';    }}

PersonBuilder

package com.ricky.builder.ch1;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 16:40 */public class PersonBuilder {    private String firstName;    private String lastName;    private String middleName;    private int age;    private String street;    private String district;    private String city;    private String province;    private boolean isFemale;    private boolean isEmployed;    public PersonBuilder(){    }    public PersonBuilder firstName(String firstName) {        this.firstName = firstName;        return this;    }    public PersonBuilder lastName(String lastName) {        this.lastName = lastName;        return this;    }    public PersonBuilder middleName(String middleName) {        this.middleName = middleName;        return this;    }    public PersonBuilder age(int age) {        this.age = age;        return this;    }    public PersonBuilder street(String street) {        this.street = street;        return this;    }    public PersonBuilder district(String district) {        this.district = district;        return this;    }    public PersonBuilder city(String city) {        this.city = city;        return this;    }    public PersonBuilder province(String province) {        this.province = province;        return this;    }    public PersonBuilder isFemale(boolean isFemale) {        this.isFemale = isFemale;        return this;    }    public PersonBuilder isEmployed(boolean isEmployed) {        this.isEmployed = isEmployed;        return this;    }    public Person create() {        return new Person(firstName, lastName, middleName, age, street, district, city, province, isFemale, isEmployed);    }}
package com.ricky.builder;import com.ricky.builder.ch1.Person;import com.ricky.builder.ch1.PersonBuilder;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 16:41 */public class PersonBuilderDemo {    public static void main(String[] args){        Person person = new PersonBuilder()                .firstName("ricky")                .lastName("fung")                .age(27)                .street("建國路")                .district("朝陽")                .city("北京市")                .province("北京")                .isFemale(false)                .isEmployed(true)                .create();        System.out.println(person);    }}
靜態內部類

SIAMessage.java

package com.ricky.builder.ch2;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 13:19 */public class SIAMessage {    private final String businessCode;    private final String type;    private final String message;    private final int timeout;    SIAMessage(String businessCode, String type, String message, int timeout) {        this.businessCode = businessCode;        this.type = type;        this.message = message;        this.timeout = timeout;    }    public static Builder custom(){        return new Builder();    }    public String getBusinessCode() {        return businessCode;    }    public String getType() {        return type;    }    public String getMessage() {        return message;    }    public int getTimeout() {        return timeout;    }    public static class Builder {        private String businessCode;        private String type;        private String message;        private int timeout;        public Builder setBusinessCode(String businessCode) {            this.businessCode = businessCode;            return this;        }        public Builder setType(String type) {            this.type = type;            return this;        }        public Builder setMessage(String message) {            this.message = message;            return this;        }        public Builder setTimeout(int timeout) {            this.timeout = timeout;            return this;        }        public SIAMessage build() {            initDefaultValue(this);            return new SIAMessage(businessCode, message, type, timeout);        }        private void initDefaultValue(Builder builder) {            if(builder.businessCode==null || builder.businessCode.length()<1){                throw new IllegalArgumentException("businessCode  can not be empty!");            }            if(builder.message==null || builder.message.length()<1){                throw new IllegalArgumentException("message can not be empty!");            }            if(builder.type==null || builder.type.length()<1){  //設定預設mime-type                builder.type = "application/json";            }            if(builder.timeout<1){                builder.timeout = 6*1000;            }        }    }    @Override    public String toString() {        return "SIAMessage{" +                "businessCode='" + businessCode + '\'' +                ", type='" + type + '\'' +                ", message='" + message + '\'' +                ", timeout=" + timeout +                '}';    }}

用戶端調用

package com.ricky.builder;import com.ricky.builder.ch2.SIAMessage;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 13:22 */public class SIAMessageDemo {    public static void main(String[] args){        //1.        SIAMessage message = new SIAMessage.Builder()                .setBusinessCode("yrd")                .setMessage("hello world")                .setTimeout(1000)                .build();        System.out.println(message);        //2.        message = SIAMessage.custom()                .setBusinessCode("yrd")                .setMessage("hello world")                .setTimeout(1000)                .build();        System.out.println(message);    }}
複雜的Builder

Builder嵌套

package com.ricky.builder.ch3;/** * ${DESCRIPTION} * * @author Ricky Fung * @create 2016-07-06 15:38 */public class Car {    private final String manufacturer;    //製造商    private final String brand;   //品牌    private final String model;   //型號    private final String producingArea;   //產地    private final String producingDate;   //生產時間    private final Engine engine;    private final Wheel wheel;    private final Light light;    Car(String manufacturer, String brand, String model, String producingArea,        String producingDate, Engine engine, Wheel wheel, Light light) {        this.manufacturer = manufacturer;        this.brand = brand;        this.model = model;        this.producingArea = producingArea;        this.producingDate = producingDate;        this.engine = engine;        this.wheel = wheel;        this.light = light;    }    public static class Builder{        private String manufacturer;    //製造商        private String brand;   //品牌        private String model;   //型號        private String producingArea;   //產地        private String producingDate;   //生產時間        private Engine engine;        private Wheel wheel;        private Light light;        public Builder(String manufacturer, String brand, String model) {            this.manufacturer = manufacturer;            this.brand = brand;            this.model = model;        }        public Builder producingArea(String producingArea){            this.producingArea = producingArea;            return this;        }        public Builder producingDate(String producingDate){            this.producingDate = producingDate;            return this;        }        public Builder engine(Engine engine){            this.engine = engine;            return this;        }        public Builder wheel(Wheel wheel){            this.wheel = wheel;            return this;        }        public Builder light(Light light){            this.light = light;            return this;        }        public Car build(){            return new Car(manufacturer, brand, model, producingArea, producingDate, engine, wheel, light);        }    }}
package com.ricky.builder.ch3;/** * 汽車發動機 * * @author Ricky Fung * @create 2016-07-06 15:42 */public class Engine {    private final String pl;  //排量    private final String maxOutputPower; //最大輸出功率    private final int rpm;  //轉速    Engine(String pl, String maxOutputPower, int rpm) {        this.pl = pl;        this.maxOutputPower = maxOutputPower;        this.rpm = rpm;    }    public static Builder custom(){        return new Builder();    }    public static class Builder{        private String pl;  //排量        private String maxOutputPower; //最大輸出功率        private int rpm;  //轉速        public Builder pl(String pl){            this.pl = pl;            return this;        }        public Builder maxOutputPower(String maxOutputPower){            this.maxOutputPower = maxOutputPower;            return this;        }        public Builder rpm(int rpm){            this.rpm = rpm;            return this;        }        public Engine build(){            return new Engine(pl, maxOutputPower, rpm);        }    }}
package com.ricky.builder.ch3;/** * 汽車輪子 * * @author Ricky Fung * @create 2016-07-06 15:40 */public class Wheel {    private String brand;    private String producingDate;    Wheel(String brand, String producingDate) {        this.brand = brand;        this.producingDate = producingDate;    }    public static Builder custom(){        return new Builder();    }    public static class Builder{        private String brand;        private String producingDate;        public Builder brand(String brand){            this.brand = brand;            return this;        }        public Builder producingDate(String producingDate){            this.producingDate = producingDate;            return this;        }        public Wheel build(){            return new Wheel(brand, producingDate);        }    }}
package com.ricky.builder.ch3;/** * 車燈 * * @author Ricky Fung * @create 2016-07-06 15:43 */public class Light {    private String brand;    private String structure;   //結構    private String producingDate;    Light(String brand, String structure, String producingDate) {        this.brand = brand;        this.structure = structure;        this.producingDate = producingDate;    }    public static Builder custom(){        return new Builder();    }    public static class Builder{        private String brand;        private String structure;   //結構        private String producingDate;        public Builder brand(String brand){            this.brand = brand;            return this;        }        public Builder structure(String structure){            this.structure = structure;            return this;        }        public Builder producingDate(String producingDate){            this.producingDate = producingDate;            return thi

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.