在 Java 的建造者樣式與構成

意圖:

將複雜物件的構造與其表示分開,以便相同的構造過程可以建立不同的表示

當你具有很少的必需屬性和許多可選屬性來構造物件時,構建器模式非常有用。要建立具有不同強制和可選屬性的物件,必須提供複雜的建構函式來建立物件 .Builder 模式提供了構建複雜物件的簡單逐步過程。

真實用例:

FaceBook 中的不同使用者具有不同的屬性,包括使用者名稱等強制屬性以及 UserBasicInfo 和 ContactInfo 等可選屬性。有些使用者只是提供基本資訊。一些使用者提供詳細資訊,包括聯絡資訊。如果沒有 Builder 模式,則必須為建構函式提供所有必需引數和可選引數。但 Builder 模式通過提供簡單的逐步過程來構建複雜物件,從而簡化了構建過程。

提示:

  1. 提供靜態巢狀構建器類。
  2. 為物件的強制屬性提供建構函式。
  3. 為物件的可選屬性提供 setter 和 getter 方法。
  4. 設定可選屬性後返回相同的 Builder 物件。
  5. 提供 build() 方法,返回複雜物件

程式碼段:

import java.util.*;

class UserBasicInfo{
    String nickName;
    String birthDate;
    String gender;
    
    public UserBasicInfo(String name,String date,String gender){
        this.nickName = name;
        this.birthDate = date;
        this.gender = gender;        
    }
    
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("Name:DOB:Gender:").append(nickName).append(":").append(birthDate).append(":").
        append(gender);
        return sb.toString();
    }
}

class ContactInfo{
    String eMail;
    String mobileHome;
    String mobileWork;
    
    public ContactInfo(String mail, String homeNo, String mobileOff){
        this.eMail = mail;
        this.mobileHome = homeNo;
        this.mobileWork = mobileOff;
    }    
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("email:mobile(H):mobile(W):").append(eMail).append(":").append(mobileHome).append(":").append(mobileWork);
        return sb.toString();
    }
}
class FaceBookUser {
    String userName;
    UserBasicInfo userInfo;
    ContactInfo contactInfo;
    
    public FaceBookUser(String uName){
        this.userName = uName;
    }    
    public void setUserBasicInfo(UserBasicInfo info){
        this.userInfo = info;
    }
    public void setContactInfo(ContactInfo info){
        this.contactInfo = info;
    }    
    public String getUserName(){
        return userName;
    }
    public UserBasicInfo getUserBasicInfo(){
        return userInfo;
    }
    public ContactInfo getContactInfo(){
        return contactInfo;
    }
    
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("|User|").append(userName).append("|UserInfo|").append(userInfo).append("|ContactInfo|").append(contactInfo);
        return sb.toString();
    }
    
    static class FaceBookUserBuilder{
        FaceBookUser user;
        public FaceBookUserBuilder(String userName){
            this.user = new FaceBookUser(userName);
        }
        public FaceBookUserBuilder setUserBasicInfo(UserBasicInfo info){
            user.setUserBasicInfo(info);
            return this;
        }
        public FaceBookUserBuilder setContactInfo(ContactInfo info){
            user.setContactInfo(info);
            return this;
        }
        public FaceBookUser build(){
            return user;
        }
    }
}
public class BuilderPattern{
    public static void main(String args[]){
        FaceBookUser fbUser1 = new FaceBookUser.FaceBookUserBuilder("Ravindra").build(); // Mandatory parameters
        UserBasicInfo info = new UserBasicInfo("sunrise","25-May-1975","M");
        
        // Build User name + Optional Basic Info 
        FaceBookUser fbUser2 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
                                                setUserBasicInfo(info).build();
        
        // Build User name + Optional Basic Info + Optional Contact Info
        ContactInfo cInfo = new ContactInfo("xxx@xyz.com","1111111111","2222222222");
        FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
                                                setUserBasicInfo(info).
                                                setContactInfo(cInfo).build();
        
        System.out.println("Facebook user 1:"+fbUser1);
        System.out.println("Facebook user 2:"+fbUser2);
        System.out.println("Facebook user 3:"+fbUser3);
    }
}

輸出:

Facebook user 1:|User|Ravindra|UserInfo|null|ContactInfo|null
Facebook user 2:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|null
Facebook user 3:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|email:mobile(H):mobile(W):xxx@xyz.com:1111111111:2222222222

說明:

  1. FaceBookUser 是一個複雜的物件,具有使用組合的以下屬性:

    String userName;
    UserBasicInfo userInfo;
    ContactInfo contactInfo;
    
  2. FaceBookUserBuilder 是一個靜態構建器類,它包含並構建 FaceBookUser

  3. userName 只是建立 FaceBookUser 的必備引數

  4. FaceBookUserBuilder 通過設定可選引數來構建 FaceBookUserUserBasicInfoContactInfo

  5. 此示例說明了使用 Builder 構建的具有不同屬性的三個不同 FaceBookUser。

    1. fbUser1 僅作為 FaceBookUser 構建,僅具有 userName 屬性
    2. fbUser2 使用 userName 和 UserBasicInfo 構建為 FaceBookUser
    3. fbUser3 使用 userName,UserBasicInfo 和 ContactInfo 構建為 FaceBookUser

在上面的示例中,使用了合成而不是在 Builder 類中複製 FaceBookUser 的所有屬性。

在創作模式中,我們將首先從像 FactoryMethod 這樣的簡單模式開始,然後轉向更加靈活和複雜的模式,如 AbstractFactoryBuilder