回答

2

我會建議針對數據傳輸對象。這是一個EJB 1.0反模式,在我看來,堅持圖層純度的人給予了價值。

值對象是有用的。它通常是一個不變的對象,像Money。他們應該是線程安全的。

+0

爲什麼當它們不可變時它們必須是線程安全的? –

+3

不可變IS線程安全。 – duffymo

+0

對不起。我以爲你說過我們必須讓它安全。 –

11

DTO是您可以在系統的邊界處使用的對象。例如,當您有一個SOAP Web服務並且您想要返回響應時,您將使用DTO。比實際的XML更容易處理,必須通過電線返回。 DTO經常由工具生成,例如基於WSDL。 DTO常常根據服務消費者的需求量身定製,並可能受性能要求的影響。

價值對象另一方面住在系統的核心。它捕獲了一些業務邏輯和可能的格式規則。它使您的代碼更安全,更具表現力。它還處理「原始癡迷」反模式。很好的例子是使用類「SocialSecurityNumber」而不是字符串。或者錢而不是小數。這些對象應該是不可變的,因此它們看起來更像是基元,並且可以在不同線程之間輕鬆共享。

例如,在假設的 '客戶訂單' 系統:

CustomerAndLastFiveOrders是DTO(優化,以避免多個網絡電話)

客戶是實體

SKU是價值對象

2

值對象是封裝爲對象時有用的東西,但它沒有標識。將它與一個實體進行比較,該實體具有身份。因此,在訂單處理系統中,Customer或Order或LineItem是指向特定人員或事物或事件的概念,因此它們是實體,其中值對象類似金錢量,並沒有自己獨立存在。例如,對於部分應用涉及計算如何在不同賬戶之間劃分支付的系統,我創建了一個不可變的Money對象,該對象具有一個分割方法,該方法返回一個Money對象數組,平均分割原始對象的數量,分配數量的代碼在寫jsp的人可以使用它的地方是非常方便的,並且他們不必將jsp與非表示相關的代碼混淆起來。

數據傳輸對象是用於將事物捆綁在一起以便跨應用程序層或層發送的包裝器。這個想法是,你想通過設計發送大量信息的方法來減少網絡往返流量。

2

有幾個很好的答案在這裏,但我會添加一個捕捉到一個關鍵的區別:

值對象沒有身份。這是包含值對象的兩個實例之間的任何比較應表明它們是相等的。數據傳輸對象雖然只用於保存值,但確實有身份。比較具有相同值但獨立創建的DTO的兩個實例並不表示它們是平等的。

實施例:

DTO dto1 = new DTO(10); 
DTO dto2 = new DTO(10); 
dto1.equals(dto2); //False (if equals is not overridden) 
dto1 == dto2; //False 

VO vo1 = VO.getInstance(10); 
VO vo2 = VO.getInstance(10); 
vo1.equals(vo2); //True 
vo1 == vo2; //True 

及其稍微難以執行在Java中值對象圖案,由於==操作符總是比較對象的身份。一種方法是實現一個對象緩存,它爲每個值返回相同的對象。

public class VO { 
    Map<Integer, WeakReference<VO>> cache = new LinkedHashMap<Integer, WeakReference<VO>>(); 
    public static VO getInstance(int value) { 
    VO cached = cache.get(value); 
    if(cached == null) { 
     cached = new VO(value); 
     cache.put(value, new WeakReference<VO>(cached)); 
    } 
    return cached.get(); 
    } 

    private int value; 
    private VO(int value) { 
    this.value = value; 
    } 
} 
6

比較DTO對象與值對象就像比較桔子和蘋果。

他們服務完全不同的情況。 DTO定義了數據如何在圖層之間傳輸的對象/類結構,而值對象在比較值時定義了相等的邏輯。

enter image description here

讓我舉例說明你,讓我們先試着先了解價值的物品: -

值對象是一個對象,其平等基礎上的價值,而 不是身份。

考慮我們創建了一個錢兩個物體下面的代碼是一個硬幣盧比,另一個是1個盧比紙幣。

Money OneRupeeCoin = new Money(); 
OneRupeeCoin.Value = 1; 
OneRupeeCoin.CurrencyType = "INR"; 
OneRupeeNote.Material = "Coin"; 

Money OneRupeeNote = new Money(); 
OneRupeeNote.Value = 1; 
OneRupeeCoin.CurrencyType = "INR"; 
OneRupeeNote.Material = "Paper"; 

現在,當您比較上述對象時,下面的比較應評估爲真,因爲1盧比鈔票等於現實世界中的1盧比硬幣。

因此,無論您是使用「==」運算符,還是使用「Equals」方法,比較結果都應爲true。默認情況下,「==」或「equals」不會計算爲真,因此您需要使用運算符重寫和方法重寫來獲得所需的行爲。你可以看到這個link,它解釋瞭如何實現相同。

if (OneRupeeCoin==OneRupeeNote) 
{ 
Console.WriteLine("They should be equal"); 
} 
if (OneRupeeCoin.Equals(OneRupeeNote)) 
{ 
Console.WriteLine("They should be equal "); 
} 

正常值對象是不變性的良好候選者;你可以從here瞭解更多關於它的信息。您可以看到this video,它描述瞭如何創建不可變對象。

現在,讓我們試着去了解DTO: -

DTO(數據傳輸對象)可以簡化移動層之間 數據傳輸的數據容器。

它們也被稱爲轉移對象。 DTO僅用於傳遞數據並且不包含任何業務邏輯。他們只有簡單的制定者和獲得者。

例如,考慮下面的調用,我們正在進行兩個調用,一個用於獲取客戶數據,另一個用於獲取產品數據。

DataAccessLayer dal = new DataAccessLayer(); 
//Call 1:- get Customer data 
CustomerBO cust = dal.getCustomer(1001); 

//Call 2:- get Products for the customer 
ProductsBO prod = dal.getProduct(100); 

所以我們可以將Customer和Product類結合到一個類中,如下所示。

class CustomerProductDTO 
{ 
    // Customer properties 
     public string CustomerName { get; set; } 
    // Product properties 
     public string ProductName { get; set; } 
     public double ProductCost { get; set; } 
} 

現在只需一個電話,我們就可以同時獲得客戶和產品數據。數據傳輸對象在兩種情況下使用,一種用於改善遠程調用,另一種用於扁平化對象分層結構;你可以閱讀這個article,它更詳細地解釋了數據傳輸對象。

//Only one call 
CustomerProductDTO cust = dal.getCustomer(1001); 

下面是完整的比較表。

enter image description here

0

數據傳輸對象是用來設置其從數據庫來在數據訪問層(DAO)的屬性值,其中作爲使用VO圖案我們可以在在DAO已經設置MVC的控制器層中設置的值層。客戶端可以訪問VO對象而不是他/她可以在jsp頁面中迭代的DTO。 你可以設置這兩個層都有一個關注點。

相關問題