2017-02-24 64 views
1

我正在尋找一種設計模式或約定來分離處理擁有實體的服務。假設我有一個處理創建主題的ThemeService。起初,ThemeService僅爲每個用戶的UserData持續使用主題,但需求更改且主題由其他實體擁有,如ThemeCollection。我的問題是,每個ThemeService都與他們的「擁有」實體緊密相連。例如:什麼是解除擁有實體服務的設計模式?

public class ThemeService{ 
    //coupled to UserData 
    createTheme(Theme t, UserData u); 
    getTheme(String name, UserData u); 
    hasTheme(String name, Userdata u); //Theme name unique within a userdata. 
    validateTheme(Theme t, UserData u); //unique name per user, valid colors, etc. 
} 

public class UserDataService{ 
    ThemeService tService; //component for themes 

    getUsername(UserData u); 
    addTheme(Theme t, UserData u){ tService.createTheme(t, u); } 
    getTheme(String name, UserData u){ tService.getTheme(name, u); } 
    hasThemes(String name, UserData u){ tService.hasTheme(name, u); } 
} 

現在ThemeService與UserData緊密耦合。如果需求不斷變化和主題可以屬於另一個實體,ThemeCollection例如,然後我真的不能再使用多從ThemeService代碼,現在需要ThemeCollection的東西更多的代碼:

public class ThemeService{ 
    //...continued or in another ThemeService class... 
    createTheme(Theme t, ThemeCollection c); 
    getTheme(String name, ThemeCollection c); 
    hasTheme(String name, ThemeCollection c); 
    validateTheme(Theme t, ThemeCollection c); 
} 

public class ThemeCollectionService{ 
    ThemeService tService; 

    getCollectionName(ThemeCollection c); 
    addTheme(Theme t, ThemeCollection c){ tService.createTheme(t, c); } 
    getTheme(String name, ThemeCollection c){ tService.getTheme(name, c); } 
    hasThemes(String name, ThemeCollection c){ tService.hasTheme(name, c); } 
} 

我會試圖讓它採用一個類似「Themeable」的泛型參數。然而,這將使實體實現的接口:

public class ThemeService{ 
    createTheme(Theme t, Themeable owner); 
    getTheme(String name, Themeable owner); 
    hasTheme(String name, Themeable owner); 
    validateTheme(Theme t, Themeable owner); 
} 

@Entity 
public class UserData implements Themeable{ 
    getUsername(); 
    getThemes(); //From Themable 
} 

@Entity 
public class ThemeCollection implements Themeable{ 
    getUsername(); 
    getThemes(); //From Themable 
} 

我不包括創建,獲取,驗證等,在主題化的界面,因爲我不想在我的實體類的業務邏輯即應希望能成爲一個純粹的數據結構(根據Robert Martin的「Clean Code」,模型中的業務邏輯是sl and不馴的,我試圖遵循一些標準)。

是否有標準的方式,模式,慣例等來解耦?我是多少有點「好」,還是在生產環境中皺起眉頭?我試圖擺脫「完成工作」的代碼,並轉向模塊化和可重用的代碼,所以任何幫助和指針都非常感謝。

編輯:「爲什麼您的服務與兩個實體耦合?」

我需要一個地方將自己的實體和所擁有的實體「縫合」在一起。例如,createTheme要的UserData:

public void createTheme(Theme t, UserData u){ 
    entityManager.persist(t); 

    if(!hasTheme(t.name(), u){ 
     u.getThemes().add(t); 
     entityManager.merge(u); 
    } 
} 

所以這個功能被耦合到的UserData,和任何類似的「主題業主」將具有類似的代碼。

+0

爲什麼你的服務與兩個實體耦合?你可以發佈一些代碼來揭示這個原因嗎? –

+0

@NiklasP我在問題的最後添加了一小段代碼。 – GuitarStrum

+0

這並不完全回答這個問題。如果'UserData'確實**擁有**''主題',爲什麼添加一個新的主題涉及除了更新'UserData'實體之外的任何內容?你提到的'拼接'應該可以在'UserDataService'中完成。 – crizzis

回答

1

一個好的方法是將主題收集的概念與用戶分離。然後,你必須:

Class Theme 
Class ThemeCollection //all theme managment things go here 
Class UserData //has a member of type ThemeCollection 

在這些方式,與管理主題functionalites在ThemeCollection並且可以在不同實體之間共享。

+0

我的問題是ThemeCollection也只是一個數據結構。 ThemeCollection需要知道如何保持自己併合並其所有者,ServiceLayer從數據結構中抽象出來。將ThemeCollection縫合到數據庫端的所有者的服務仍然存在耦合問題,它必須「知道」它的所有者才能合併它。 – GuitarStrum

+0

向ThemeCollection添加新主題時,擁有者不需要自行更新。因爲它已經堅持與ThemeCollection的關係,並且不關心它裏面的內容。只有ThemeCollection將被合併。 – sara

+0

是的,但我之前評論的意思是,現在ThemeCollection與Theme中的位置相同:ThemeCollection仍然需要與UserData以及未來可能的其他實體綁定在一起。 – GuitarStrum