首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为所拥有的实体解耦服务的设计模式是什么?

为所拥有的实体解耦服务的设计模式是什么?
EN

Stack Overflow用户
提问于 2017-02-24 14:06:36
回答 1查看 511关注 0票数 1

我正在寻找一种设计模式或约定来解耦处理所拥有实体的服务。假设我有一个ThemeService,它处理主题的创建。起初,ThemeService只为每个用户的UserData持久化主题,但需求发生了变化,主题被其他实体所拥有,比如ThemeCollection。我的问题是,每个ThemeService都与它们的“所属”实体紧密耦合。例如:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
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); }
}

我很想让它接受一个泛型参数,该参数实现类似于“可传递”的东西。但是,这将使实体实现一个接口:

代码语言:javascript
复制
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
}

我没有将创建、获取、验证等功能包含在logic接口中,因为我不希望在我的实体类中包含业务逻辑,而实体类应该是纯数据结构(根据Robert Martin的"Clean Code",在模型中包含业务逻辑是草率的,我正在尝试遵循一些标准)。

有没有一种标准的方式、模式、约定等来解耦这一点?我所拥有的东西或多或少是“好的”,还是在生产环境中不被接受?我正在努力摆脱“完成工作”的代码,转向模块化和可重用的代码,所以任何帮助和指针都是非常感谢的。

编辑:“为什么您的服务耦合到两个实体?”

我需要一个地方来“缝合”拥有的实体和拥有的实体在一起。例如,UserData的createTheme:

代码语言:javascript
复制
public void createTheme(Theme t, UserData u){
   entityManager.persist(t);

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

所以这个函数被耦合到UserData,任何类似的“主题所有者”都会有类似的代码。

EN

回答 1

Stack Overflow用户

发布于 2017-02-24 15:22:27

一个好的方法是将主题集合的概念从用户中分离出来。然后你就有了:

代码语言:javascript
复制
Class Theme
Class ThemeCollection  //all theme managment things go here
Class UserData  //has a member of type ThemeCollection

通过这些方式,与管理主题相关的功能组件在ThemeCollection中,并可以在不同的实体之间共享。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42431900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档