Java Spring 设计:多合一组件?

有时 Spring 组件可能如下所示:


@Service

public final class SomeService {

    @Autowired

    private SomeService2 someService2;

    @Autowired

    private SomeService3 someService3;

    @Autowired

    private SomeService4 someService4;

    // … and many other services

    @Autowired

    private SomeDao someDao;

    @Autowired

    private SomeDao2 someDao2;

    @Autowired

    private SomeDao3 someDao3;

    // … and many other DAOs


}

换句话说,Spring 组件有很多服务和 DAO,这些服务和 DAO 在其他 Spring 组件中大部分是重复的。恕我直言,它有以下缺点:


用于自动装配大多数相同组件的不必要(样板)代码

有时由于组件之间的循环引用,可能会出现 Spring 上下文加载错误

如何使用组合所有服务或所有 DAO 的一体化组件。它将仅包含指向 Spring 组件的链接,其中没有任何业务逻辑:


@Service

public final class AllServices {

    @Autowired

    private SomeService2 someService2;

    @Autowired

    private SomeService3 someService3;

    @Autowired

    private SomeService4 someService4;

    // … and many other services


    // get methods to get some service

    public someService getSomeService(){};

并将其注入其他组件:


@Service

public final class SomeService {

    @Autowired

    private AllServices serv;

    @Autowired

    private AllDaos daos;

    @Autowired

    private Environment env;


// inside some code

serv.getSomeService().processData();

恕我直言,如果没有循环引用问题,它看起来会更简洁……


这种方法有什么优点和缺点?


守候你守候我
浏览 162回答 2
2回答

繁花如伊

第二种方法可能看起来很吸引人,首先想到的是众所周知的外观模式,所以我完全可以理解这一点。但是,我认为第一种模式实际上会更好地工作,原因如下:你说“万能”的服务可以解决循环依赖好吧,循环依赖通常指向错误/糟糕的设计,并且是代码本身的味道,因此将其隐藏在外观后面不会改善系统,解决循环依赖会。此外,如果从由“AllServices”调用的实际服务中,您需要调用其他服务(同样,保留了糟糕的设计),那么代码可能会再次通过 AllServices,因此循环依赖仍然存在。使用第二种设计假设这个“AllServices”类将被系统的所有组件使用,但在这种情况下,它变成了一个“一个中心点”,并且在这个类中重构可能会变得疯狂——所有组件/他们的测试可能会受到影响此服务的初始化本身可能会变得一团糟,因为您可能不想维护具有 20-30 个输入参数的构造函数,您将求助于字段注入(如示例中),这本身就很糟糕,因为如果你想以某种方式初始化它,可能来自测试,或者你想知道什么应该被模拟,什么不是,以什么顺序,等等。

海绵宝宝撒

第二种方法可能看起来更干净,但很难知道哪个服务连接到服务/DAO,因此很难重构或执行/决定任何更改将导致哪个回归。这意味着它会影响软件的灵活性这是一个重要的差异使不同选择第一个选项恕我直言
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java