java - 将多个@Service 和@Repository 类分组到包装器中是一种反模式吗?

标签 java spring design-patterns dependency-injection anti-patterns

问题有点反常。我与我的同事就以下模式发生了争论:

@Component
public class MetaService {

    public static UserService userService;
    public static GroupService groupService;   
    public static PermissionService permissionService;            
    // ...more fields

    @Autowired
    public MetaService(UserService userService,
                       GroupService groupService
                       PermissionService permissionService) {

        MetaService.userService = userService;
        MetaService.groupService = groupService;
        MetaService.permissionService = permissionService;           
    }
}

基本上,MetaService 是多个 Spring bean @Service 类的入口点/包装器。 @Repository beans 类还有一个类似的 MetaDao 包装器:

@Component
public class MetaDao {

    public static UserDao userDao;
    public static GroupDao groupDao;
    public static PermissionDao permissionDao;
    // ...more fields   

    @Autowired
    public MetaDao(UserDao userDao,
                   GroupDao groupDao,
                   PermissionDao permissionDao) {

        MetaDao.userDao = userDao;
        MetaDao.groupDao = groupDao;
        MetaDao.permissionDao = permissionDao;
    }
}

拥有这样一个元类的想法是通过提供简洁的 API 来调用 @Service 来减少 @RestController@Service 类中的代码库@Repository 方法,例如:

@RestController
public class UserController {

    @PostMapping
    public UserCreateResponse createUser(UserCreateRequest request) {
        MetaService.userService.createAndReturn(userEntity);
        // other service calls
    }
}

换句话说,这是在每个 @Controller 等中为每个 @Service 设置 @Autowired 字段/构造函数的替代方法。我认为这种方法大大减少了样板重复代码。

好吧,我的同事们说:这种方法使代码更难理解/维护,因为将 @Service 组件组合在一个地方隐藏了使用它们的其他组件的依赖模型。换句话说,如果有为 UserController 类声明的字段。快速找出 UserController 依赖哪些组件会更容易。此外,在进行单元测试时更难模拟此类依赖项。而最重要的 这种方法是 super 反模式。虽然我可以同意 mock 的部分,但其他一切对我来说似乎都很荒谬。

问题是,这真的是一种反模式吗?

最佳答案

这对我来说显然是一种反模式。

  1. 为什么需要这个? UserController 需要 UserService,为什么它会包含一个包含它不需要的 GroupServiceMetaService

  2. 不确定您的 MetaDAO 应该做什么,将具有特定关系的对象捆绑在一起?我非常怀疑这是否适用于大多数对象(一个用户可以在多个组中吗?他可以拥有多个权限吗?)这应该服务于什么领域相关性?或者它们应该是 @Repository

  3. 静态成员是public static,但不是final - 违反封装。它基本上是一个实现不当的单例模式。

  4. MetaService 也可以实现所有三个接口(interface)并维护与存储库的关系。如果实际域由单个服务正确表示,则无需在 Controller 和存储库之间放置两层服务。

此外,我认为这个问题属于 https://softwareengineering.stackexchange.com .

关于java - 将多个@Service 和@Repository 类分组到包装器中是一种反模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50699781/

相关文章:

java - 如何在java中绘制gif动画?

java - Thymeleaf 迭代对象列表

java - 如何用策略实现单例?

design-patterns - 包含其他类集合的类的设计(操作方法)

java - 我对检查数字是否为质数的程序的逻辑有疑问。 (我必须使用3种方法)

java.lang.VerifyError : (class: org/apache/jasper/compiler/JspUtil, 方法:<clinit> 签名:()V) 函数参数不兼容

java - 在 Java 8 中计算两个日期之间的天数

java.sql.SQLException : Connection is read-only. hibernate中不允许导致数据修改的查询

spring - 如何记录 Spring Data MongoDB 执行的查询?

java - DAO 设计模式与 DBUnit 代码