Dependency injection都有人质疑??
Proffitt认为DI流行的唯一原因是Mocking,真不知道想说什么了。DI提供了什么?DI是IOC相对于Lookup方式更优雅的实现,DI可以帮我们组装对象,注入依赖的对象,连定位对象的代码都可以省去,使得胶水代码几乎为零,DI提供了可插拔的松耦合的编程方式,但几乎不需要要求你的代码为之专门做什么来支持,唯一的要求是提供构造函数或setter方法来注入,setter方法即时在没有DI的时候,实现它都是一个很好的选择,因为你可以在运行期间切换依赖的对象,同时为测试提供了方便。DI同时提供了生命周期的管理,你的类无需实现单例模式,就可以享受单例带来的便捷性,全局的访问点,实例的共享。你无需自己定义Factory,单例了,DI提供了通用的,即拿即用的基础设施。使用DI带来什么,不光是Mocking更容易了,测试更容易了,更重要的是它提供了通用的,即拿即用的基础设施,带来了良好的编成习惯,以及松耦合的系统。
不管怎样,我真的希望人们能够承认DI除了单元测试之外,没什么其他有说服力的应用。
不管怎样,我真希望你承认当时说的时候脑子是被驴踢过了...,呵呵
后来又有人质疑Spring的价值,你看看Spring带来的价值吧:
(下面最早我写在CSDN的博客:Spring先进思想与实用主义的集大成者):
Spring一个开源的JavaEE轻量级框架,它的目的是提供更好的编程模型,从而使J2EE开发更容易。Spring的许多理念一直引领着J2EE的轻量级开发的潮流。通过对Spring的学习,切实地感觉到了Spring领先的理念以及实用主义框架与规范驱动的EJB之间的差别。
Spring它不重复发明轮子,而是对现有的优秀的J2EE框架进行更好的抽象,提供贯穿应用各个层的更一致的编程模型,从而简化J2EE的开发。所以它和WEB层的框架如Struts,JSF和持久层框架Hibernate,JDO这些单层的框架有着很大的区别。
Spring使用控制反转(IoC)的和面向方面的编程架构,给POJO提供企业级的服务,这在J2EE中是特别有意义的。传统的EJB组件模型,严重依赖于EJB容器,EJB试图使用工具来弥补J2EE规范的不足,通过使用EJB容器生成代码来管理组件或生成服务。一个好的框架要比生成的代码灵活的多,生成代码技术可能在开发阶段能够提供快捷高效的方式来减少样板式的代码,但在整个项目生命周期的后期(维护和排除bug)就会暴露出其隐含的复杂性。POJO这样可脱离容器的服务,一方面可以方便在各种环境下被重用,另一方面由于脱离了容器可以更方便的进行单元测试。许多J2EE技术都太底层了,像JNDI,JDBC,对于程序员,需要写许多样板式的代码和捕捉异常并需要小心妥善的获取连接关闭连接,这些J2EEAPI和服务没有提供给程序员易于使用的视图,以及更好的编程模型。而Spring就是为了提供给程序员更好的J2EE编程模型和更易用的视图而存在的。事实上Spring一致而又良好的编程模型让你避免了这种底层的操作,Spring会妥善处理好这些枯燥而又重复的底层操作。
Spring的核心IOC容器,提供了一个强大的管理对象、服务和资源的方式。它使用DI(依赖注入)这种优秀的理念,由容器来创建管理对象,并注入其依赖的对象,从而创建出可直接使用的服务和资源,而无须使用者担心如何装配对象以及其依赖的对象,无须考虑如何获取这些对象。DI要比传统的EJB的IOC要先进的多,EJB使用JDNI来定位服务,这种lookup式的管理方式,用户需要主动的去从Context中去“拉”取所需要的资源,并且需要妥善的处理JDNI的连接释放,以及异常的处理。而这些底层的操作显然转移了用户对核心业务的处理。Spring的核心IOC容器对应用程序的侵入性达到了最小,这些对象是POJO的,完全不依赖于具体的容器和环境,可以方便的进行单元测试。而传统的EJB的服务定位方式需要依赖于EJB容器,并且如果试图mock出Context来进行单元测试,将是困难的。同时EJB并不能提供所有类型对象的管理。
Spring提供的AOP(面向方面编程)框架。AOP作为OOP的一种有益的补充,提供了另外一种思考代码的方式,AOP关注是横切的方面,将横切的服务或代码,抽离并组织成为一个模块或单独的服务,避免了样板式的代码遍布在各个服务中,让每个服务更专心的去实现其核心的业务。而这些抽离出来的服务,可以方便的织入到需要的这些服务代码的服务中,为其提供辅助性的服务。AOP分离了核心服务和辅助性服务的关注点,而这种分离不需要付出任何的代价(继承指定的接口或类),整个过程对于核心业务类来说是透明的,从而使得代码更具有内聚性和OO性。Spring提供了使用动态代理的实现和AspectJ的集成,提供了最优秀最强大的AOP编程模型。通过使用AOP增强POJO的功能,从而让POJO能够具有胜任企业级的服务的能力,提供了与传统EJB完全不同的实现方法。EJB通过EJB容器生成代码来提供管理和声明性的服务,而这种方式丢失了很大的灵活性,而AOP这种方式可以合并组合各种最佳的服务,并且这些服务可以进行定制,AOP在声明式事务管理、审计、安全控制、异常处理、缓存处理等方面,提供了一种更好的编程方式。
Java一直滥用check异常,不当check的异常,会强制你捕捉根本无法恢复的异常,这不仅使你的代码有“险处丛生”的感觉,更重要的是你每次处理这些毫无意义的异常会分散你的核心业务,让你的代码更难读。并且像Java的JDBC提供的异常体系太粗,一个SQLException概括了之。Spring提供了一致的细粒度uncheck异常体系,无论你使用JDBC,Hibernate,JDO,JPA,ibatis,它都把这些具体框架的异常转化成spring的异常体系中。
Spring鼓励使用基于接口而不是类的编程方式。基于接口的编程方式提供了可插拔的服务方式,通过在编码中指定依赖的接口,可以透明而方便的替换掉具体的实现类。特别是在Spring容器的管理之下,只需要在配制文件中替换掉其依赖实现就可以切换到需要的具体的实现类。这种方式构造的系统具有很好的松耦合性。