用靜態工廠方法代替構造器
為了獲得一個類的例項,可以使用公有構造器,也可以提供一個公有的靜態工廠方法,他只是一個返回類的例項的靜態方法
public static Boolean valueOf(boolean b) { //Boolean是bool的一個Java裝箱類 return b ? Boolean.TRUE : Boolean.FALSE; }
靜態工廠方法的優點:
- 他是有名稱的,閱讀程式碼更加直觀,例如Big Integer(int,int ,Random) 返回的BigInteger
-
不必在每次呼叫他們的時候建立一個新物件,他可以重複利用,Boolean.valueOf(boolean)不會建立物件
- 能夠為重複的呼叫返回相同的物件,極大的提升效能
- 可以返回原返回型別的任何子型別的物件
- 返回的物件的類可以隨著每次呼叫而發生變化,這取決於靜態工廠方法的引數值設定
- 方法返回的物件所屬的類,在編寫包含該靜態工廠方法的類時可以不存在
靜態工廠方法的缺點:
- 類如果不含公有的或者受保護的構造器,就不能被子類化
- 程式設計師很難發現他們
傳統的方式是new
class People{ String name; int age; int weight; } People People=new People();
靜態工廠方法可以在類中新增一個公有靜態方法來返回一個例項:
class People{ String name; int age; int weight; public static People getPeople(){ return new People(); } } People firstPeople=People.getPeople();
遇到多個構造器引數時要考慮使用構建器
靜態工廠和構造器的缺點都是不能很好的擴充套件大量的可選引數,大部分程式設計師對於這樣的情況使用重疊構造器。
public class Person { private final int age; private final int height; private final int weight; private final int sex; public Person (int age) { this(age,0); } public Person (int age, int height) { this(age,height,0); } public Person (int age, int height, int weight, int sex) { this.age = age; this.height = height; this.weight = weight; this.sex = sex; } }
遇到許多可選的構造器引數的時候,還有第二種代替方法,javaBean方式,先呼叫一個無參構造器來建立物件,再呼叫setter方法設定每個必要的引數,以及每個相關的可選引數
public class Person { private int age = 1; private int height = 2; private int weight = 3; private int sex = 1; public Person() {} //Setters public void setAge(int val) {age=val;} public void setHeight(int val){height=val;} public void setWeight(int val){weight=val;} public void setSex(int val){sex=val;} } Person person = new Person(); person.setAge(2); person.setHeight(100); person.setWeight(100); person.setSex(1);
但是JavaBean模式存在嚴重的缺點,構造過程被分散到幾個呼叫中,在構造過程中JavaBean可能處於不一致的狀態。
public class Person { private final int age; private final int height; private final int weight; private final int sex; // 私有建構函式,只能透過Builder來訪問 private Person(Builder builder) { this.age = builder.age; this.height = builder.height; this.weight = builder.weight; this.sex = builder.sex; } // Builder類 public static class Builder { private final int age; private int height; private int weight; private int sex; // Builder的建構函式 public Builder(int age) { this.age=age; } // 鏈式設定方法 public Builder setAge(int age) { this.age = age; return this; } public Builder setHeight(int height) { this.height = height; return this; } public Builder setWeight(int weight) { this.weight = weight; return this; } public Builder setSex(int sex) { this.sex = sex; return this; } // 構建Person物件 public Person build() { return new Person(this); } } private Person(Builder builder){ age = builder.age; height = builder.height; weight = builder.weight; sex = builder.sex; } } // 使用Builder模式建立Person物件 Person person = new Person.Builder() .setAge(2) .setHeight(100) .setWeight(100) .setSex(1) .build();
如果類的構造器或者靜態工廠中有多個引數,設計者種類,Builder模式就是一種不錯的選擇