IOC(依赖注入)模式反思

来源:互联网 发布:工业设计网络教育 编辑:程序博客网 时间:2024/06/05 20:36

IOC,是现在很火的设计模式,就像当年的FactorySingleton模式一样。IOC模式为我们提供了真正(?)的松散耦合,但是松散耦合真的这么酷吗?紧耦合真的一无是处吗?不见得。

首先,使用IOC模式就必然会依赖于一些IOC容器,除非你直接使用反射(-_-),比如Spring,这对于勾结的独立性是不利的,试想,如果每次使用java.lang.String的时候都必须import org.springframework…。对于一些要求响应速度的系统而言,IOC的使用必然会降低系统性能(new 的速度肯定比Class.forName块),缓存?忘记它吧,我已经强调响应速度了。再说,IOC跟缓存和池没有必然联系呀。

其次,IOC模式的大量使用会降低一些复杂模块的可读性,要知道,如果你不能写出很好的文档(多数人都是如此),那么代码就是你唯一可以与其他人沟通的语言。如果阅读代码的人不懂IOC,不会使用Spring呢,他如何理解你那些接口的实现?

第三,IOC容器的大量使用会造成额外的维护成本,很显然,你现在不仅仅需要维护你的代码,还需要维护你的applectionContext.xml,如果是WEB应用,则需要注意维护哪些Context-Param。尤其是,虽然代码中不存在耦合关系,但是耦合关系都在配置文件中,你在写出松散耦合的代码的同时也必须去写紧耦合的配置文件,对于一个大型系统而言,大量的配置文件的管理本身就必须付出高昂的代价。

最后,我认为真正意义上的松耦合是不存在的——是的,你可以“依赖”接口编程——但是毕竟还是“依赖”了。既然没有绝对的松散耦合,那么我们是否可以考虑在一定范围内使用紧耦合呢?ArrayListCollection是紧耦合,你是否觉得不便呢,ArrayListIterator更是紧耦合,难道Iterator不好用吗?

考虑一下传统的工厂模式吧,它在一定程度上体现了IOC的思想,但是又没有完全的实现IOC。你可以使用工厂模式实现接口编程,但是依赖关系仍然需要在代码中体现。Hibernate是公认的优秀产品,它没有使用IOC,大量的Factory充斥其中,但是Hiberante的质量和升级速度有目共睹。也许你会说,IOC容器提供了很多底层的东西,例如缓存和对象生命周期管理等,以Spring为例,缓存倒是有,可是生命周期管理就不见得,事务管理还是需要客户介入。再说了,这些都是容器提供的,IOC模式并没有要求。之所以谈这些,主要是考虑实现一个带有缓存和“挂钩点”的工厂,这个工厂提供对象的创建和pool&cache管理但是不提供依赖关系管理。

那么IOC这个模式在哪里使用呢,我认为,应该在构件这个级别使用。构件应该是一个封装的很好的模块,它提供独立的、具有实际意义的功能。通过对构件的粒度的设计控制IOC使用的密度。而构件的内部,可以使用传统的工厂模式,也可以什么模式都不用^_^。只要提供清晰准确的接口,并且封装接口在构件内部的实现,那么即使使用public变量都没有关系!