1. 程式人生 > >構造器模式

構造器模式

構造器模式


概述

  • 概念:構造器模式 Builder Pattern1
  • 作用:使複雜物件的構造演算法和它的表示分離,以便同一個構造演算法,可以建立不同的表示1
  • 場景1
    • 場景一
      • 類的構造方法2
        • 當類中有新增屬性時,需要擴充構造方法,新增屬性,當可選引數過多時,構造物件時就很容易傳錯引數
        • 當類中某些屬性可選時,需要定製構造方法,即某些屬性可空,某些情況構造物件不需要傳值
    • 程式碼示例
    package test;
    
    import java.io.Serializable;
    
    /**
     * 使用者物件
     * @author test
     * 1.建立類
     * 2.添加當前類的成員變數,區分變數:必須與可選;新增 Set Get 方法
     * 3.建立靜態內部類 - 當前的建造類
     * 4.新增內部類的成員變數,拷貝外部類的成員變數
     * 5.新增外部類構造方法,構造方法入參為內部類,構造方法屬性賦值
     * 6.新增內部類構造方法,構造方法入參為必須成員變數
     * 7.新增內部類成員方法,可選成員變數賦值
     * 8.新增內部類建造方法,返回外部類的物件
     */
    public class User implements Serializable {
    
        private static final long serialVersionUID = 3601470141407549788L;
    
        /**
         * 使用者編號 required 成員變數
         */
        private Integer id ;
    
        /**
         * 使用者名稱稱 required 成員變數
         */
        private String name ;
    
        /**
    
         * 使用者年齡 optional 成員變數
         */
        private Integer age ;
    
        /**
         * 使用者身高 optional 成員變數
         */
        private Integer height ;
    
        public Integer getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public Integer getHeight() {
            return height;
        }
    
        private User (UserBuild userBuild){
            this.id = userBuild.id ;
            this.name = userBuild.name ;
            this.age = userBuild.age ;
            this.height = userBuild.height ;
        }
    
        public String toString(){
            StringBuilder toStringBuilder = new StringBuilder(this.name.length() * 4);
            toStringBuilder.append("User ").append("id:").append(this.id).append(",name:").append(this.name).append(",age:")
                    .append(this.age).append(",height:").append(this.height);
            return toStringBuilder.toString();
        }
    
        /**
         * User 類建造者類
         * @author test
         */
        private static class UserBuild {
    
            /**
             * 使用者編號 required 成員變數
             */
            private Integer id ;
    
            /**
             * 使用者名稱稱 required 成員變數
             */
            private String name ;
    
            /**
    
             * 使用者年齡 optional 成員變數
             */
            private Integer age ;
    
            /**
             * 使用者身高 optional 成員變數
             */
            private Integer height ;
    
            public UserBuild(Integer id ,String name){
                this.id = id ;
                this.name = name ;
            }
    
            public UserBuild age(Integer age){
                this.age = age ;
                return this ;
            }
    
            public UserBuild height(Integer height){
                this.height = height ;
                return this ;
            }
    
            public User build(){
                return new User(this);
            }
        }
    
        public static void main(String[] args) {
    
            User user = new UserBuild(1,"2").age(3).height(4).build();
            System.out.println(user.toString());
            System.out.println(user.getId());
            System.out.println(user.getName());
            System.out.println(user.getAge());
            System.out.println(user.getHeight());
        }
    }
    
    
    • 其他方式
      • 快速新增Builder內部類的方法——PO類上新增 Guava @Builder 註解3
      • 新增引數時不必修改構造方法——PO類上新增 Guava @AllArgsConstructor 註解3
    • 場景二
      • 將複雜物件的構造與物件的屬性分離,呼叫方只需要指定需要呼叫的型別而無需關注具體的建造過程及細節2
      • 程式碼示例
package test;

import java.io.Serializable;

/**
 * 動物實體類
 * 動物身體由頭、腳組成
 * @author test
 */
public class Animal implements Serializable{
    private static final long serialVersionUID = 2610315450660664668L;

    /**
     * 頭
     */
    private Head head = new Head();

    /**
     * 腳
     */
    private Foot foot = new Foot();

    /**
     * 頭的數量
     * @param num 數量
     */
    public void setHeadNum(int num){
        head.setNum(num);
    }

    /**
     * 設定腳的數量
     * @param num
     */
    public void setFootNum(int num){
        foot.setNum(num);
    }

    public Head getHead() {
        return head;
    }

    public void setHead(Head head) {
        this.head = head;
    }

    public Foot getFoot() {
        return foot;
    }

    public void setFoot(Foot foot) {
        this.foot = foot;
    }

    public String toString(){
        StringBuilder sb = new StringBuilder("");
        sb.append("Head num:").append(this.head.getNum()).append(",Foot num:").append(this.foot.getNum());
        return sb.toString();
    }
}

package test;

import java.io.Serializable;

/**
 * 頭
 * @author test
 */
public class Head implements Serializable {
    private static final long serialVersionUID = 7657725082250430948L;

    /**
     * 數量
     */
    private Integer num ;


    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }
}


package test;

import java.io.Serializable;

/**
 * 腳
 * @author test
 */
public class Foot implements Serializable{
    private static final long serialVersionUID = -9198575656926734237L;

    private Integer num ;

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }
}

package test;

/**
 * 動物構造器
 * @author test
 */
public abstract class AnimalBuilder {

    protected Animal animal = new Animal();

    public abstract void setHeadNum();

    public abstract void setFootNum();
}

package test;

/**
 * 大象
 * @author test
 */
public class ElephantAnimal extends AnimalBuilder {

    @Override
    public void setHeadNum() {
        animal.setHeadNum(1);
    }

    @Override
    public void setFootNum() {
        animal.setFootNum(4);
    }
}

package test;

/**
 * 螞蟻
 * @author test
 */
public class AntAnimal extends AnimalBuilder {

    @Override
    public void setHeadNum() {
        animal.setHeadNum(1);
    }

    @Override
    public void setFootNum() {
        animal.setFootNum(6);
    }
}

package test;

/**
 * 指揮者
 * @author test
 */
public class AnimalDirector {
    private AnimalBuilder animalBuilder;

    public AnimalDirector(AnimalBuilder animalBuilder){
        this.animalBuilder = animalBuilder;
    }

    public Animal createAnimal(){
        animalBuilder.setFootNum();
        animalBuilder.setHeadNum();
        return animalBuilder.animal;
    }
}

package test;

public class AnimalClient {

    public static void main(String[] args) {

        AnimalBuilder elephant = new ElephantAnimal();
        AnimalDirector director = new AnimalDirector(elephant);
        Animal animal = director.createAnimal();
        System.out.println(animal);
    }
}



  1. 設計模式—構造器模式 ↩︎ ↩︎ ↩︎

  2. 建造者(Builder)模式 的若干使用場景 ↩︎ ↩︎

  3. PO類上新增 Guava @Builder 註解 ↩︎ ↩︎