寫在前面
系統邏輯編寫中,咱們主要經過切割和封裝成一個個的JavaBean來實現的,在建立JavaBean對象咱們主要有三種方案,可是哪一種方案更利於將來系統的擴展和演進呢?咱們來分析下。ide
構造函數方式
構造函數方式主要的表現形式以下:函數
UserInfo userInfo1 = new UserInfo("xxx", 28); UserInfo xxxxxx = new UserInfo("xxx", "yyy", 28); UserInfo xxxxxx1 = new UserInfo("xxx", "yyy", 28, 20200560);
構造函數一般須要可伸縮性,也就是參數列表須要重載。有些時候我不得不傳入null進行初始化。ui
// 不合理的構造使用示範 UserInfo xxxxxx = new UserInfo(null, null, 28);
並且不能直觀看出這些參數所表明的的含義,這有可能引起致命的錯誤,咱們將同類型的username和address互換位置依然成功初始化了對象,不會顯式的引起構建錯誤,這是不合理的。this
另外若是參數列表比較長,有七八個的話,代碼是很是冗長的。設計
JavaBean方式
這種方式是最經常使用的建立對象的方法。只須要使用無參構造函數,而後爲每一個成員變量設置setter方法。code
UserInfo userInfo = new UserInfo(); userInfo.setUsername("xxx"); userInfo.setAge(28);
這種方式很是廣泛,可是存在一個很明顯的問題,對於某個Bean咱們能夠在任何場景,任何邊界以外進行set的操做,這樣就顯得很是難以管理了,也不符合咱們領域化設計的思想,咱們應該採用充血模型方式,將可對屬性形成修改的能力收斂起來,而不是讓其能夠採用set的方式隨意訪問。對象
Builder方式
咱們須要在目標對象(這裏是UserInfo)內部建立了一個靜態類,一般簡單地稱爲Builder。Builder聲明瞭一系列方法來設置對象屬性的值,而後將其返回Builder自己,完成全部調用後,咱們調用Builder的無參build方法進行目標對象的初始化。blog
public class UserInfo { private String userName; private String address; private int age; private int time; // 私有化無參構造函數 private UserInfo() { } public static class Builder { private String userName; private String address; private int age; private int time; public Builder userName(String userName) { this.userName = userName; return this; } public Builder address(String address) { this.address = address; return this; } public Builder age(int age) { this.age = age; return this; } public Builder time(int time) { this.time = time; return this; } public UserInfo build() { UserInfo info = new UserInfo(); info.userName = this.userName; info.address = this.address; info.age = this.age; info.time = this.time; return info; } } public String getUserName() { return userName; } public String getAddress() { return address; } public int getAge() { return age; } public int getTime() { return time; } @Override public String toString() { return "UserInfo{" + "userName='" + userName + '\'' + ", address='" + address + '\'' + ", age=" + age + ", time=" + time + '}'; } }
若是採用Lombok,能夠這麼寫:get
@Builder public class UserInfoBean { private String userName; private String address; private int age; private int time; public String getUserName() { return userName; } public String getAddress() { return address; } public int getAge() { return age; } public int getTime() { return time; } @Override public String toString() { return "UserInfoBean{" + "userName='" + userName + '\'' + ", address='" + address + '\'' + ", age=" + age + ", time=" + time + '}'; } }
而後初始化對象就能夠這麼寫:class
public class Test { public static void main(String[] args) { UserInfo info = new UserInfo.Builder() .userName("xxx") .address("yyy") .age(28) .time(20200560) .build(); System.out.println("info = [" + info + "]"); System.out.println("info.userName = [" + info.getUserName() + "]"); UserInfoBean bean = UserInfoBean.builder() .userName("xxx") .build(); System.out.println("bean = [" + bean + "]"); System.out.println("info.address = [" + info.getAddress() + "]"); } }
這種方式是我最喜歡的一種方式,特別是當Bean自己具備更加複雜的業務的時候,經過這種方式能夠實現更加的收斂,不是經過屬性的直接get和set,而是採用充血模型方式,以func的方式進行能力訪問。