spring - 您如何应对 Spring beans 增加的额外复杂性?

标签 spring coding-style inversion-of-control design-guidelines

我编写软件已经很多年了,并且一直试图创建富有表现力、清晰可读、可维护、健壮的代码。最近,我加入了一个使用 Spring 托管对象开发 Web 应用程序的团队。但我对这项技术感到非常不舒服。对我来说,感觉所有的封装和信息隐藏原则、数十年软件工程的成就都被抛弃了。我清楚地看到使用控制反转容器的优点,将系统依赖项从程序代码移到配置文件中。但现在,我认为 Spring 的使用方式只是增加了不必要的复杂性,而没有产生任何好处。

使用 Spring 创建 Web 应用程序支持 Bean,对象不再清晰地组织在模块中,也不再具有最小的可见性。相反,现在有一个单一的全局 Bean namespace 。因此,对象往往会得到像“pendingOrderCustomerName”这样的糟糕名称,更糟糕的是,这些名称甚至不能清楚地标识一个定义良好的实体,因为 bean 定义可以来自各种定义源,从公开指定的位置收集: Spring bean 不是简单地定义为包中的类,而是从 xml 文件组装而成,具有自由覆盖的可能性和松散定义的关系。

例如,当我在纯java中具有“Account”类型时,在“my.webstore”包中,我通常可以在一个地方(“my/webstore”)了解该类型的属性、关系和能力/Account.java”文件。 “Account”的实例作为与帐户一起使用的对象中的引用而存在,任何实例的状态都由该类精确定义。然而,对于 Spring beans,事情变得更加复杂:“Account”的实例现在存在于全局名称下,位于容器管理的范围内,具有从 xml 文件组装的状态,沿着基于命名模式的文件搜索路径找到...

要了解对象的作用及其行为方式,您只需阅读其程序源代码的日子已经一去不复返了。今天,您需要对象的 java 源代码(可能很复杂,难以理解),此外您还必须找到可能更改该对象的任何配置文件,这并不容易,因为您必须找出配置可能来自的所有方式你必须找出它们相互覆盖的顺序

也许这只是一个品味问题,但我也想知道为什么人们更喜欢冗长、笨拙的 xml 语法,如下所示:

  <bean id="p1" class="Point" scope="prototype">
    <property name="x">
      <value>20</value>
    </property>
    <property name="y">
      <value>80</value>
    </property>
  </bean>

在此:

  p1 = new Point(20,80);

这个例子可能看起来有些夸张,但我告诉你我见过更糟糕的!

我无意批评 Spring 框架本身,它非常强大,在很多情况下都是一个优秀的成分。我关心的是如何防止误操作,如何保持可维护性,如何保证质量和稳定性,如何寻找依赖关系,如何记录代码......您的经验是什么?

最佳答案

正如您所看到的,如果您没有正确理解面向对象设计的原理,很容易误用 Spring。 Spring IoC 容器(让我们暂时忘记其余的,因为 Spring 旗下有大量的库)当您使用它来执行以下操作时,它确实会大放异彩:

  • 定义组件模型(例如 Controller 、服务、存储库及其依赖项)
  • 集中组件依赖项查找(例如替换服务定位器、JNDI 查找或其他无状态组件检索策略)
  • 用技术方面(例如事务管理、缓存、访问控制等)装饰组件
Spring 或任何 IoC 容器将允许您拥有统一的组件模型,删除大量样板代码,并将横切关注点隔离到集中的方面。它还应该插入您实现一个由松散耦合组件组成的系统,专注于实现业务逻辑,从长远来看,这将提高可读性、可测试性和可维护性。

当然,如果你开始定义Account,你不会获得任何东西(实际上会失去很多)。和 Point s 作为 Spring 组件。这些仍然应该被设计为实体或值对象。它们仍然应该是正确包的一部分,并且应该应用适当的可见性修饰符。如果您的应用程序未利用 IoC 容器,则仍应使用您将使用的策略来实例化、操作和管理它们。

看来您已经了解声音设计原则,所以我鼓励您相信自己的直觉。如果一个类是可重用的(通常是无状态的)组件,那么将其声明为 Spring 组件并将其注入(inject)到适当的位置。如果您不确定,请将其保留为普通的非托管类并正常使用它。您将了解声明组件在哪里有意义以及在哪里没有意义。

我还鼓励您研究如何利用 @Component<context:component-scan>声明以减少 XML 占用空间。

祝你好运。

关于spring - 您如何应对 Spring beans 增加的额外复杂性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16893554/

相关文章:

spring - UserDetails getPassword 在 Spring Security 3.1 中返回 null。如何获取当前登录用户的密码?

spring - 使用 Spring boot 在单个浏览器 session 中使用多个 OAuth2 客户端

c++ - 使用 .size() 与 const 变量进行循环

c# - OnDataBinding 与 Inline : pros, 缺点和开销

.net - 是否有更喜欢约定而不是配置的 .NET IoC?

spring - PROPAGATION_NESTED vs PROPAGATION_ Spring 需要吗?

spring - 从 alfresco activiti 过程中调用 spring bean

Java 代码约定 : Using 'default' as a variable name

c# - Ninject 字段注入(inject)在构造函数类中不起作用

architecture - 领域驱动设计中的层