2017-02-14 65 views
0

我在建模實體時有點矛盾。@瞬間vs裝飾者

我們有一個具有6-8個實例變量的實體。其中兩個實際上並沒有保存在數據庫中,但僅用於做一些驗證或在UI中顯示。因此,當我們獲取實體時,我們用一些外部查找來填充。

現在,根據我的同事之一,其更好的做法是使用裝飾器代替使用@Transient。我在某種程度上同意。因爲它闡明瞭DB代表的實際模型。

但它會增加對一些案件的補充樣板(如業務我可以命名實體MyEntityBO,但如果我用它的UI ......再次名稱將是有點混亂。

我的問題是,什麼場景它更好地使用@Transient而不是裝飾器,反之亦然

+1

無論其他字段或方法。出於這個原因,您不應該直接從UI中使用實體。您應該有一個特定於視圖的模型,它是專門爲該視圖設計的模型的表示。該視圖模型屬於用戶界面。視圖模型可以通過合成封裝原始模型,但這本身不是裝飾器。這是除非你的應用程序是簡單的CRUD,在這種情況下只需要使用@Transient。 – plalx

+0

你可以顯示示例代碼來給出一個想法如何在這裏添加裝飾模式? –

+0

@plalx在我的情況下,它並不總是用戶界面。對象也用於其他驗證。組合似乎更好地處理這種情況。創建2個對象。 ObjectUI,ObjectBO。所以只有用戶界面需要的吸氣劑纔會在那裏。所以不小心,這些東西不應該被用戶界面看到,但應該存在於主要實體中,例如ID /密碼可以隱藏。 (再次,這裏的反指向是「@IgnoreJson」:)我試圖理解「@Transient」在哪些情況下仍然可行。如果像你說的應用程序只是CRUD,那麼只需要「@Transient」 –

回答

0

對於兩者都使用實體,這不是一個好的做法:數據庫映射和UI映射平。始終考慮單一責任原則。實體應該只負責數據庫映射,不要再做。您應該爲UI表示創建DTO圖層。但在這種情況下,您應該創建轉換器,這很無聊,我建議使用Mapstruct - http://mapstruct.org。 如果您必須使用@Transient,這是第一個出現錯誤的跡象,請記住它。祝你好運:)

@Entity 
public class User { 
    @Id 
    Long id; 
    String name; 
} 

public class UserDto{ 
    Long id; 
    String name; 
} 

public class UserConverter{ 
    public UserDto toDto(User user) { 
     if (user == null) return null; 
     UserDto dto = new UserDto(); 
     dto.setId(user.getId()); 
     dto.setName(user.getName()); 
     return dto; 
    } 

    public User toEntity(UserDto dto){...} 
} 

而且在DTO對象,你可以創建你需要某種目的

+0

問題是維護這個DTO。它創建了不必要的冗長代碼。但如果我將其組合起來,它會使它更易於維護。我的疑問是關於「@Transient」,他們爲什麼創建一個實體只是應該映射DB結構?它有什麼動機。在哪裏更加可行......但我現在明白......單一責任原則。 –

+0

我不推薦使用這個包裝器,你應該分離你的dao層,服務層和UI層。理想情況下,您應該從數據庫獲取對象,執行業務邏輯,在UI端構建需要的對象併發送它。如果你發送包裝,它意味着實體是在包裝對象內,這是錯誤的,因爲你發送你的域對象到UI。它也可能導致LazyInitException,因爲您的分離實體已發送到UI。您應該將完全構建的DTO對象發送到UI。其實DTO模式是如何處理LazyInitException的最好方法之一。 – idmitriev

+0

想想你的架構,你的圖層應該是糟糕的耦合,並使用他們自己的數據。如果你的DTO沒有任何方法,這將是完美的,它只是一個愚蠢的數據。用戶界面負責處理這些數據 – idmitriev

-1

使用裝飾模式的主要缺點是代碼維護可能是一個問題(從我的經驗) 我強烈建議你去@Transient

+0

您可以詳細說明一下「代碼維護」嗎?你看到了哪些問題或不雅情緒在哪裏產生問題? –

+0

在我們的項目中,Decarator模式有許多類似於similer的對象,因此在維護過程中它變得令人頭疼。另外,如果您計劃遷移(在將來),它比暫時模式更不方便。但是,如果您擁有很少的對象,不是一個問題。我自己面臨的問題,所以建議。乾杯 – Akshay