JavaSpring设计:多功能组件?
有时弹簧组件可能如下所示:JavaSpring设计:多功能组件?,java,spring,design-patterns,Java,Spring,Design Patterns,有时弹簧组件可能如下所示: @Service public final class SomeService { @Autowired private SomeService2 someService2; @Autowired private SomeService3 someService3; @Autowired private SomeService4 someService4; // … and many other services
@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组件中重复。IMHO有以下缺点:
用于自动连接大多数相同组件的不必要样板代码
有时,由于组件之间的循环引用,可能会发生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();
如果没有循环引用的问题,它看起来会更简洁
这种方法的优缺点是什么?第二种方法可能看起来更干净,但很难知道哪个服务连接到服务/DAO,因此很难重构或决定任何更改将导致哪种回归。意味着it影响软件灵活性
这是一个重要的区别,它决定了选择第一个选项,因为第二种方法看起来更干净,但很难知道哪个服务连接到服务/DAO,因此很难重构或决定任何更改将导致哪种回归。意味着it影响软件灵活性
这是一个重要的区别,它决定了选择第一个选项。第二个方法可能看起来很吸引人,一开始我会想到一个著名的立面模式,所以我完全可以理解这一点 然而,我认为第一种模式实际上会更好,原因如下: 您说全能服务可以解决循环依赖 嗯,循环依赖通常指向错误/糟糕的设计,并且代码本身就有味道,因此将其隐藏在门面后面不会改善系统,解决循环依赖会改善系统。此外,如果从AllServices调用的实际服务中,您希望再次调用其他服务,则保留了错误的设计,那么代码可能会再次通过AllServices,因此循环依赖关系仍然存在 使用第二种设计假设系统的所有组件都将使用这个AllServices类,但在这种情况下,它将成为一个中心点,在这个类中进行重构可能会变得疯狂——所有组件/它们的测试都可能受到影响 此服务的初始化本身可能会变得一团糟,因为您可能不想维护一个具有20-30个输入参数的构造函数,您将求助于字段注入,就像示例中那样,这本身就很糟糕,因为如果您想以某种方式初始化它,可能是通过测试,或者你想知道什么应该被嘲笑,什么不应该被嘲笑,按照什么顺序,等等
第二种方法可能看起来很吸引人,一开始会想到一种众所周知的外观模式,所以我完全可以理解这一点 然而,我认为第一种模式实际上会更好,原因如下: 您说全能服务可以解决循环依赖 嗯,循环依赖通常指向错误/糟糕的设计,并且代码本身就有味道,因此将其隐藏在门面后面不会改善系统,解决循环依赖会改善系统。此外,如果从AllServices调用的实际服务中,您希望再次调用其他服务,则保留了错误的设计,那么代码可能会再次通过AllServices,因此循环依赖关系仍然存在 使用第二种设计假设系统的所有组件都将使用这个AllServices类,但在这种情况下,它将成为一个中心点,在这个类中进行重构可能会变得疯狂——所有组件/它们的测试都可能受到影响 此服务的初始化本身可能会变得一团糟,因为您可能不想维护一个具有20-30个输入参数的构造函数,您将求助于字段注入,就像示例中那样,这本身就很糟糕,因为如果您想以某种方式初始化它,可能是通过测试,或者你想知道什么应该被嘲笑,什么不应该被嘲笑,按照什么顺序,等等
这两个都是消费者服务执行过多功能的明显例子。你应该重构你的服务,以便每个人都履行一个职责。好的一点是,每次你有一个以上的服务可能是2个,根据用例,你应该考虑重构,你的类打破了5个坚实的原则的单一责任原则。再仔细研究一下,这两个都是消费者服务执行太多功能的明显例子。你应该重构你的服务,这样每个人都能执行一个单一的职责。好的一点是,每次你有一个以上的服务,可能是2个,这取决于用例,你应该考虑重构,你的类是
打破了五项坚实原则中的单一责任原则。再仔细研究一下,我认为使用第二种方法查找Spring组件的依赖项并不是那么困难。此外,Spring组件应该足够独立,不会与其他组件产生大的回归。@sergkunz在第二种方法中,您可以有循环依赖关系,只是有更多的杂乱。我认为使用第二种方法查找Spring组件的依赖关系并不难。此外,Spring组件应该足够独立,不会对其他组件进行大的回归。@sergkunz在第二种方法中,您可以有循环依赖关系,只需要更多的混乱