1. 程式人生 > >對各種DTO,VO,POJO等的理解

對各種DTO,VO,POJO等的理解

首先複製一下:

JavaBean 是一種JAVA語言寫成的可重用元件。為寫成JavaBean,類必須是具體的和公共的,並且具有無引數的構造器。JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性。眾所周知,屬性名稱符合這種模式,其他Java 類可以通過自身機制發現和操作這些JavaBean 的屬性。

VO即value object值物件
主要體現在檢視的物件,對於一個WEB頁面將整個頁面的屬性封裝成一個物件。然後用一個VO物件在控制層與檢視層進行傳輸交換。

DTO (經過處理後的PO,可能增加或者減少PO的屬性):
Data Transfer Object資料傳輸物件
主要用於遠端呼叫等需要大量傳輸物件的地方。
比如我們一張表有100個欄位,那麼對應的PO就有100個屬性。
但是我們介面上只要顯示10個欄位,
客戶端用WEB service來獲取資料,沒有必要把整個PO物件傳遞到客戶端,
這時我們就可以用只有這10個屬性的DTO來傳遞結果到客戶端,這樣也不會暴露服務端表結構.到達客戶端以後,如果用這個物件來對應介面顯示,那此時它的身份就轉為VO。

POJO(POJO是一種概念或者介面,身份及作用隨環境變化而變化) :
POJO有一些private的引數作為物件的屬性。然後針對每個引數定義了get和set方法作為訪問的介面
plain ordinary java object 簡單java物件
即POJO是一個簡單的普通的Java物件,它不包含業務邏輯或持久邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不繼承或不實現任何其它

Java框架的類或介面。
POJO物件有時也被稱為Data物件,大量應用於表現現實中的物件。
一個POJO持久化以後就是PO。
直接用它傳遞、傳遞過程中就是DTO
直接用來對應表示層就是VO

概念上的理解就是這樣,分層思想是對的,但分層過多往往就會造成理解的問題,各種物件的分類在概念上是對的,然而很多時候很多概念的提出者卻沒給出相應的實現方案或者指準則,這很多時候就是問題所在;

首先還是對Setter,Gette,構造器,序列化等方法的討論(我覺得區別就在這裡),有句話說得好,你每個屬性都給提供getter,setter,那幹嘛不一開始直接將屬性宣告為public,這不是脫褲子放屁麼,getter,setter一個讀一個寫,分工明確;至於構造器,構造器簡單分就是有參構造器和無參構造器(這不廢話麼。。。),但是我覺得這恰恰是理解問題的關鍵點,你想用好這東西,你得明白他為什麼提供給你這個,怎麼用好,而不是能用則用(我見過很多瞎寫的);

什麼時候應該提供無參構造器?

1.當引數值對構建物件不必要的時候,你只要確定了這一條,那麼你也該仔細想想你為什麼不提供singleton或者protype

2.引數對構建物件很重要,但是往往會有預設值的時候,此時更好的做法是提供工廠方法體現構造型別;

如Excutors框架

有參構造器?

1.引數值或者引數值組對唯一確定一個物件或者對當前物件建立提供必需的初始值是有必要的,必須提供有參構造器

getter.settter

根據封裝性,提供了getter,setter之後的物件根本就沒有屬性封裝可言了,一味的提供getter,setter有害無益

作為指導準則,

1.如非必要,請不要提供setter

2.對用於構造引數的屬性,儘量不要提供setter

3.setter中不要提供任何其他邏輯程式碼(值判斷等等,setter是最後一層,就是純賦值),(某些框架提供了@Getter,@Setter註解)

為了加以區分,應用內部提供的按以上標準,可不提供

Serializable

對外傳輸物件,請考慮實現特殊資料結構,(廢除瞎寫的getter,setter),並在應用內部跑的pojo提供轉化方法

如下例項;

public class User {
    //必須屬性
    private int id;
    
    //非必須屬性,在設計時儘量仔細考慮應用實際情況;
    private String name;
    private String password;
    
    //禁止無參構造
    private User(){}
    
    
    public User(int id) {
        this.id = id;
    }

    //此類必須屬性不提供setter
    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public  UserValueHolder convert(){
        //提供相關方法
        return null;
    }
    
    //VO,DTO等對邏輯基本無關,應儘量隱藏,且命名上應給予相關提示,比如XXXValueHolder
    static class UserValueHolder implements Serializable {
        //提供序列值
        
        int id;
        String name;
        String password;
        
        public User generate(){
            User user = new User(id);
            return user;
        }
    }
}