是将多个@Service和@Repository类分组为包装反模式?

Mik*_*kov 7 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;           
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@RestController
public class UserController {

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

换句话说,这是@Autowired在每个@Service内部都有字段/构造函数的替代@Controller方法.在我看来,这种方法大大减少了样板重复代码.

好吧,我的同事们说:这种方法使代码更难理解/维护,因为@Service在一个地方组合组件会隐藏使用它们的其他组件的依赖模型.换句话说,如果有为UserController类声明的字段.快速找出哪些组件UserController取决于它会更容易.另外,模拟这样的依赖进行单元测试更加困难.而这种方法最重要的是超反模式.虽然我同意嘲笑部分,但其他一切对我来说都是荒谬的.

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

Nik*_*las 4

关于OOP的原则,我发现通过public static属性甚至final关键字来暴露分组服务是一个不好的原则。我认为这种方法增加了复杂性:如果要添加更多 DAO/服务怎么办?- 那么你将被迫扩大MetaDao班级规模MetaSerice

通过这个外观暴露这些服务,另一个不必要的层将允许真正不需要的UserController使用和服务 - 有必要吗?touch它破坏了封装。使用这种广泛使用的方法:

@RestController
public class UserController {

    @Autowired
    private final UserService userService;

    // ...
}
Run Code Online (Sandbox Code Playgroud)