2017-02-24 82 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