你如何应对春豆增加的额外复杂性?

时间:2013-06-03 09:21:57

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

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

使用Spring创建webapp支持bean,对象不再在模块中清晰地组织,并且不再具有尽可能小的可见性。相反,现在有一个全局的bean名称空间。因此,对象倾向于得到像'pendingOrderCustomerName'这样糟糕的名称,更糟糕的是,这些名称甚至不能清楚地标识定义明确的实体,因为bean定义可以来自各种定义源,从公开指定的位置收集: Spring bean不是简单地定义为包中的类,而是由xml文件组装而成,具有自由覆盖的可能性和松散定义的关系。

例如,当我在普通java中有一个类型“Account”时,在包“my.webstore”中,我通常可以在一个地方知道该类型的属性,关系和能力,“my / webstore /Account.java“文件。 “帐户”实例作为使用帐户的对象中的引用存在,任何实例的状态都由类精确定义。然而,使用Spring bean,事情变得更加复杂:“帐户”的实例现在存在于全局名称下,在容器管理的范围内,具有从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框架,它在许多情况下非常强大且是一个很好的组成部分。我关心的是如何防止滥用,如何保持可维护性,如何保证质量和稳定性,如何找到依赖关系,如何记录代码......您的体验是什么?

2 个答案:

答案 0 :(得分:2)

如您所见,如果您不能正确理解面向对象设计的原则,则很容易滥用Spring。 Spring IoC容器(让我们暂时忘记其余部分,因为在Spring保护伞下有一个庞大的库组合)当你使用它时真的很棒:

  • 定义组件模型(例如控制器,服务,存储库及其依赖项)
  • 集中组件依赖项查找(例如,替换服务定位器,JNDI查找或其他无状态组件检索策略)
  • 用技术方面装饰组件(例如,事务管理,缓存,访问控制等)

Spring或任何IoC容器将允许您拥有统一的组件模型,删除大量样板代码,并将跨领域问题隔离到集中方面。它还应该促使您实现一个由松散耦合的组件构成的系统,该系统侧重于实现业务逻辑,从长远来看,这将提高可读性,可测试性和可维护性。

当然,如果您开始将AccountPoint定义为Spring组件,那么您将无法获得任何收益(实际上会损失很多)。这些仍应设计为实体或值对象。它们应该仍然是正确包装的一部分,并且应该应用适当的可见性修改器。如果您的应用程序没有使用IoC容器,它们仍应使用您将使用的策略进行实例化,操作和管理。

看起来你已经知道合理的设计原则,所以我鼓励你相信你的直觉。如果一个类是一个可重用(通常是无状态的)组件,那么将它声明为一个Spring组件并将其注入适当的位置。如果您不确定,请将其保留为正常的非托管类并正常使用。您将会看到声明组件的位置和不合理的位置。

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

祝你好运。

答案 1 :(得分:0)

Spring的许多功能都被误用了。我曾经像你一样思考,但最近当我更多地了解Spring时,我开始喜欢它,除非任何依赖注入框架都会这样做,如果我有选择,我可能更喜欢Guice而不是Spring。 / p>

问题似乎是人们知道如何使用Spring但不知道为什么。特别是不使用时。当您有多个实现时,Spring bean很有用。这是依赖注入的亮点。在你的例子中,我当然希望Point没有任何其他实现,因此Spring再次被误用了。

对我来说,Guice motivation促使我更多地了解依赖注入,它同样适用于Spring。

也就是说,您可以结帐Spring's annotations,了解如何将配置和代码保存在一个位置。