Java 依赖注入的思考

什么是依赖注入

这里展开一下,控制反转,依赖注入,是说把控制的主动权转移了,不由调用者决定要调谁来实现,而是由被注入决定谁去实现

 

依赖注入到底有啥好处呢?

我使用过一些 依赖注入框架——但是他们的实现在我看来,就是在使用类似反射的机制!!

不让对象 new 出来,就降低了依赖!

——难道,我写一个简单的 反射类,我就相当于写出了一个 依赖注入框架吗???

一个反射类可以实现的功能;为什么 那些大型公司会用一个团队来开发?

依赖注入的优势

首先我们需要知道,人们在很长的一段时间里都是利用控制反转原则规定:应用程序的流程取决于在程序运行时对象图的建立。通过抽象定义的对象交互可以实现这样的动态流程。而使用依赖注入技术或者服务定位器便可以完成运行时绑定。

使用依赖注入可以带来以下好处:

依赖的注入和配置独立于组件之外。
因为对象是在一个独立、不耦合的地方初始化,所以当注入抽象方法的时候,我们只需要修改对象的实现方法,而不用大改代码库。
依赖可以注入到一个组件中:我们可以注入这些依赖的模拟实现,这样使得测试更加简单。
可以看到,能够管理创建实例的范围是一件非常棒的事情。按我的观点,你app中的所有对象或者协作者都不应该知道有关实例创建和生命周期的任何事情,这些都应该由我们的依赖注入框架管理的。

利用面向对象的思想。打个比方
你需要锤子,你可以
1、自己去造。用java的话说就是调用者创建被调用者
2、你可以要找到生产锤子的工厂,向工厂购买即可。对应java的工厂模式。
3、你可以打电话找到卖锤子的商店,让人把锤子送货上门。对应spring的依赖注入

以上第1种办法,要求被调用的Java类出现在调用者的代码里。无法实现二者之间的松耦合
第2种办法,调用者无须关心被调用者具体实现过程,只需要找到符合某种标准(接口)的实例,即可使用
第3种办法,调用者无须自己定位工厂,程序运行到需要被调用者时,系统自动提供被调用者实例。调用者和被调用者通过spring管理。他们的关系由spring维护

反射最终还是需要new来实现一个实例化对象,而依赖注入真正解决了这个问题

 

Java中的依赖注入

依赖注入的确是个简单的技术,但是spring这些框架的强大,远不是因为它会依赖注入,反射中,最终不还是创建出了实例吗?spring默认情况下获取一个bean是单例的,而不是new出实例给你。而且正是有了这种接口式的注入设计,才会有这么多开源技术可以通过spring简单整合运行,节省了大量的整合工作

再来个实例,某个类要使用第三方实现来处理快递流程,它注入了一个标准接口,里面有查运费,查收货地,查快递配送状态等标准方法。而实现类有多种,比如申通的实现,圆通的实现。
现在可以用spring进行配置了,喜欢用哪家的就注入哪家的,还可以注入个工厂类来同时使用多家的。反射怎么搞?从申通的实现换到圆通实现时,把要反射的类名字全部改一遍吗?

好吧好吧,跑偏了,其实博主是搞安卓开发的,这里再引用安卓中的例子来解释

 

android中的依赖注入

举个大家最常见却又经常忽略的例子吧

现在非常流行的MVP框架,他的很多思想非常不错,比如把M层与V层分离,这是V层专注UI,逻辑控制由P层来控制。这是其相比MVC来说非常大的一个痛点。

但是,他也同时违背了很多java设计的原则。

比如开闭原则(V层大改时,P层也要修改)依赖倒置,接口隔离(形式上解耦,但职责分工角度耦合,V层与P层的联系)单一职责原则(V层直接持有P层的引用)。。。。

好吧,原谅我扯远了,MVP部分的优化以及MVVM的一些对比后面再另写一篇专门讲。这里我们来看看V层持有P层的引用,这个问题完全是可以有下面的主角(Dagger2)来实现解耦

依赖注入,可以把实例化的过程交给被调用者,把控制的主动权转移了。

使用了Dagger2,不由V层来决定要调哪个P层,而是由被注入决定谁去实现,V层专心UI,测试时专心在P层进行。

大型框架具备 “依赖注入”,AOP(调用拦截,android中也支持),对象生命周期的控制,其他的对象控制

猜你喜欢

转载自blog.csdn.net/qq_39037047/article/details/84100909