建立和銷燬物件(一)

Heinrich♣發表於2024-11-04
用靜態工廠方法代替構造器
為了獲得一個類的例項,可以使用公有構造器,也可以提供一個公有的靜態工廠方法,他只是一個返回類的例項的靜態方法
public static Boolean valueOf(boolean b) { //Boolean是bool的一個Java裝箱類
    return b ? Boolean.TRUE : Boolean.FALSE;
}

靜態工廠方法的優點:
  1. 他是有名稱的,閱讀程式碼更加直觀,例如Big Integer(int,int ,Random) 返回的BigInteger
  2. 不必在每次呼叫他們的時候建立一個新物件,他可以重複利用,Boolean.valueOf(boolean)不會建立物件
    1. 能夠為重複的呼叫返回相同的物件,極大的提升效能
  3. 可以返回原返回型別的任何子型別的物件
  4. 返回的物件的類可以隨著每次呼叫而發生變化,這取決於靜態工廠方法的引數值設定
  5. 方法返回的物件所屬的類,在編寫包含該靜態工廠方法的類時可以不存在
靜態工廠方法的缺點:
  1. 類如果不含公有的或者受保護的構造器,就不能被子類化
  2. 程式設計師很難發現他們
傳統的方式是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模式就是一種不錯的選擇

相關文章