對於一個有著大量可選引數的類來說,我們在構建的時候一般有一下幾種方式:
####一:重疊構造模式: 比如Android中的View
public class MyView extends View {
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
複製程式碼
這種模式我們可以根據具體場景使用不同的構造方法來建立一個MyView物件。這種方式在引數個數較少時可行,但是當如果一個類引數過多並且有相同型別的引數,我們在建立物件的時候必須小心的檢查具體呼叫的那一個構造方法,因為我們很容易顛倒引數的順序,此時編譯器也並不會報錯,(比如在View的構建方法中我把defStyleAttr和defStyleRes兩個方法的順序顛倒)。
####二:JavaBean模式,這應該算是我們最常用的一種形式
public class User {
private long uid;
private String nick;
private int gender;
private int age;
private String email;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
複製程式碼
建立一個JavaBean物件:
User user = new User();
user.setAge(23);
user.setGender(1);
user.setNick("superman");
user.setEmail("abc@xx.com");
user.setUid(10001);
複製程式碼
這種模式程式碼看上去邏輯很清晰,也解決了多個構造器的不足,但是它自身也有一個缺陷:在涉及到多執行緒的時候,我們在構造物件的過程中物件可能處於不一致的狀態。
####三:Builder構建模式(比如Android中的我們常用的AlertDialog)
public class Desk {
private int length;
private int width;
private int height;
private int weight;
private int color;
private int price;
public static class Builder {
private int length = 0;
private int width = 0;
private int height = 0;
private int weight = 0;
private int color = 0;
private int price = 0;
public Builder length(int length) {
this.length = length;
return this;
}
public Builder width(int width) {
this.width = width;
return this;
}
public Builder height(int height) {
this.height = height;
return this;
}
public Builder weight(int weight) {
this.weight = weight;
return this;
}
public Builder color(int color) {
this.color = color;
return this;
}
public Builder price(int price) {
this.price = price;
return this;
}
public Desk build() {
return new Desk(this);
}
}
private Desk(Builder builder) {
length = builder.length;
width = builder.width;
height = builder.height;
weight = builder.weight;
color = builder.color;
price = builder.price;
}
}
複製程式碼
構建一個物件:
Desk.Builder builder = new Desk.Builder();
Desk desk = builder.length(2000)
.width(1600)
.height(1400)
.weight(1000)
.color(Color.BLACK)
.price(500)
.build();
複製程式碼
這種方式兼具上面兩種方式的優點並解決了兩種方式各自的缺陷,並且程式碼看上去也很容易閱讀。但是它自身也還是有一些缺陷的,在建立一個物件的時候必須先構建一個他的Builder物件,還是增加了一些開銷。