Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';这是一种设计模式,用于为自有实体解耦服务?_Java_Jpa_Design Patterns_Service Layer_Decoupling - Fatal编程技术网

Java 什么';这是一种设计模式,用于为自有实体解耦服务?

Java 什么';这是一种设计模式,用于为自有实体解耦服务?,java,jpa,design-patterns,service-layer,decoupling,Java,Jpa,Design Patterns,Service Layer,Decoupling,我正在寻找一种设计模式或约定来解耦处理自有实体的服务。假设我有一个ThemeService,它负责创建主题。起初,ThemeService只是为每个用户的UserData保存主题,但需求变化和主题由其他实体拥有,比如ThemeCollection。我的问题是,每个电子服务都与它们的“所属”实体紧密耦合。例如: public class ThemeService{ //coupled to UserData createTheme(Theme t, UserData u);

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

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); }
}
现在,电子服务与用户数据紧密耦合。如果需求发生了变化,主题可以属于另一个实体,例如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
}
我不在可主题化接口中包括create、get、validate等,因为我不希望实体类中的业务逻辑应该是纯数据结构(根据Robert Martin的“干净代码”,模型中的业务逻辑是草率的,我试图遵循一些标准)

是否有一种标准的方式、模式、惯例等来将其解耦?我所拥有的或多或少是“好的”,还是在生产环境中不受欢迎?我试图摆脱“完成任务”的代码,转而使用模块化和可重用的代码,因此非常感谢您的帮助和指点


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

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

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

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

因此,此函数与UserData耦合,任何类似的“主题所有者”都会有类似的代码。

一个好方法是将主题集合的概念与用户分离。那么你有:

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

通过这种方式,与管理主题相关的功能都在电子集合中,可以在不同的实体之间共享。

为什么您的服务耦合到两个实体?你能发布一些代码来说明原因吗?@NiklasP我在问题的末尾添加了一个简短的片段。这并不能完全回答问题。如果
UserData
确实拥有一个
主题
,那么除了更新
UserData
实体之外,为什么还要添加一个新主题呢?您提到的“缝合”可能应该在
UserDataService
中完成。在您的代码中创建紧密耦合的是
UserDataService
ThemeService
的引用。无论涉及修改一个或多个数据实体,每个服务方法都应该真正对应于单个业务逻辑操作。因此,很少需要一个服务依赖于另一个服务(同时,实现业务目标可能需要多个存储库;但这些存储库不应包含除持久化和删除实体所涉及的逻辑之外的任何逻辑)。@crizzis发布1:我想让主题逻辑更接近于组件。UserData拥有一个主题,但将来该主题可能会被其他东西所拥有。发布2:我试图将ThemeService逻辑从UserDataService中分离出来,因为UserDataService将成为一个大类(即,用户将有主题、书签、设置等),但我想在这种情况下我应该有一个UserThemeService,专门将用户和主题缝合在一起?我的问题是,ThemeCollection也只是一个数据结构。eCollection需要知道如何保持自身并合并其所有者,ServiceLayer将其从数据结构中抽象出来。在数据库端将主题集合缝合到其所有者的服务仍然存在耦合问题,需要“知道”其所有者才能合并。向主题集合添加新主题时,所有者不需要更新自身。因为,它已经坚持了它和ThemeCollection的关系,不关心它里面是什么。只有ThemeCollection将被合并。是的,但我在前面的评论中的意思是,现在ThemeCollection与Theme处于相同的位置:ThemeCollection仍然需要与UserData以及将来可能的其他实体绑定在一起。