構造方法的參數太多,如何解決?

你在寫代碼的過程當中應該也遇到因過構造方法的參數太多、構造方法重載太多,而不知道使用哪一個方法建立對象的問題;或者參數傳着傳着就錯位了。


好比 Person 類,包含 id、姓名、性別、身高、體重屬性。爲了方便建立對象,咱們通常使用全部屬性做爲參數提供一個最全的構造方法,而後按需提供部分屬性的若干構造方法。代碼以下:面試

 
 
package constxiong.interview.design;
/** * 對象人 * @author ConstXiong */public class Person {
   /**     * id     */    private final int id;    /**     * 姓名     */    private final String name;    /**     * 性別     */    private final String sex;    /**     * 身高     */    private final Double height;    /**     * 體重     */    private final Double weight;    public Person(int id, String name) {        this(id, name, null);    }    public Person(int id, String name, String sex) {        this(id, name, sex, null);    }    public Person(int id, String name, String sex, Double height) {        this(id, name, sex, height, null);    }
   public Person(int id, String name, String sex, Double height, Double weight) {        this.id = id;        this.name = name;        this.sex = sex;        this.height = height;        this.weight = weight;    }}


當咱們須要建立一個只知道 id、姓名、性別的對象時,調用第 2 個構造方法便可安全

 
 
Person person = new Person(1, "ConstXiong", "男");


這樣作存在問題:示例中才 5 個參數,實際開發中隨着參數的增多,建立對象會愈來愈困難,須要肯定參數的數量與構造方法中的位置;代碼可讀性不好;容易參數顛倒且很難排查。
爲解決上述問題,會有第 2 種作法,提供默認構造方法與屬性的 set 方法。session

 
 
package constxiong.interview.design;
/** * 對象人 * @author ConstXiong */public class Person {
   /**     * id     */    private int id;    /**     * 姓名     */    private String name;    /**     * 性別     */    private String sex;    /**     * 身高     */    private Double height;    /**     * 體重     */    private Double weight;    public Person() {    }
   public void setId(int id) {        this.id = id;    }
   public void setName(String name) {        this.name = name;    }
   public void setSex(String sex) {        this.sex = sex;    }
   public void setHeight(Double height) {        this.height = height;    }
   public void setWeight(Double weight) {        this.weight = weight;    }}


這種的方式 Person 對象能夠這樣建立app

 
 
Person person = new Person();person.setId(1);person.setName("ConstXiong");person.setSex("男");person.setHeight(1.70);person.setWeight(150.0);

這樣作解決了構造方法多個參數和可讀性的問題,可是引入了新的問題,就是沒法作到屬性參數在構造完以後是不可改變的,致使存在數據不安全的問題。

第 3 種方式,使用 Builder 模式。代碼以下ide

 
 
package constxiong.interview.design;
/** * 對象人 * @author ConstXiong */public class Person {
   /**     * id     */    private final int id;    /**     * 姓名     */    private final String name;    /**     * 性別     */    private final String sex;    /**     * 身高     */    private final Double height;    /**     * 體重     */    private final Double weight;    public static class Builder {        private int id;        private String name;        private String sex;        private Double height;        private Double weight;        public Builder() {        }        public Builder id(int id) {            this.id = id;            return this;        }        public Builder name(String name) {            this.name = name;            return this;        }        public Builder sex(String sex) {            this.sex = sex;            return this;        }        public Builder height(Double height) {            this.height = height;            return this;        }        public Builder weight(Double weight) {            this.weight = weight;            return this;        }        public     Person build() {            return new Person(this);        }    }    private Person(Builder builder) {        this.id = builder.id;        this.name = builder.name;        this.sex = builder.sex;        this.height = builder.height;        this.weight = builder.weight;    }}


建立 Person 對象的代碼性能

Person person = new Person.Builder()                .id(1)                .name("ConstXiong")                .sex("男")                .height(1.70)                .weight(150.0)                .build();


Builder 模式須要注意是,Builder 類是靜態內部類、類的構造方法是 private 的且參數爲 Builder 對象。
Builder 模式不只能夠解決構造過程數據安全、參數過多、可讀性的問題,還能夠自動填充參數、生成對象前對參數之間的關係進行合法校驗等...
固然 Builder 模式也帶了新的問題:ui

  • 創新對象前,必須建立 Builder 對象,多一些性能開銷。對性能要求極高的場景下慎用。
  • Builder 模式跟 一、2 兩種方式比,代碼行數更多,顯得有點囉嗦。


因此說,軟件開發通常沒有完美的解決方法,只有不一樣場景的最優解決辦法;一種方法能解決某些問題,必然帶來其餘問題。
Builder 模式就很是適合使用較多參數構造對象、須保證對象構造後的屬性字段安全的場景。

PS:Java 面試題彙總在:這裏this

相關文章
相關標籤/搜索