Android中的依赖注入:Dagger函数库的使用(一)

——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢——

原文链接:http://antonioleiva.com/dependency-injection-android-dagger-part-1/

本文Gitbooks链接:http://asce1885.gitbooks.io/android-rd-senior-advanced/content/androidzhong_de_yi_lai_zhu_ru_ff1a_dagger_han_shu_ku_de_shi_yong_ff08_yi_ff09.html

在这个新系列中,我将解释什么是依赖注入,它的主要目的是什么,以及在Android工程中如何Dagger函数库实现它,Dagger是目前最流行的专为Android设计的依赖注入函数库。

本文是之前的文章《Android中MVP的实现》的后续之作,因为我相信读者中有一部分人会很乐意看到这两个特性在同一个工程中实现,而且我认为它们可以很好的协同工作。

本文将仅介绍基本的理论知识来奠定基础。理解依赖注入的概念以及它存在的理由是很重要的,否者我们会认为得到的好处不如付出的努力。

什么是依赖注入

如果我们想要注入依赖,首先要理解依赖是什么。简单的说,依赖是我们代码中两个模块之间的耦合(在面向对象语言中,指的是两个类),通常是其中一个模块使用另外一个提供的功能。

为什么依赖是危险的?

从上层到底层依赖都是危险的,因为我们在某种程度上把两个模块进行耦合,这样当需要修改其中一个模块时,我们必须修改与其耦合的模块的代码。这对于创建一个可测试的app来说是很不利的,因为单元测试要求测试一个模块时,要保证它和app中其他模块是隔离的。为了做到这一点,我们需要使用mocks代替依赖,想象一下这样的代码:

public class Module1{
   private Module2 module2;

   public Module1(){
      module2 = new Module2();
   }

   public void doSomething(){
      ...
      module2.doSomethingElse();
      ...
   }
}

如何在不测试doSomethingElse函数的前提下测试doSomething函数呢?如果测试失败,是哪个函数导致的呢?我们不得而知。如果doSomethingElse函数在数据库中保存数据或者向服务器端发起API请求,那么事情将变得更加糟糕。

每当敲下new关键字我们都应该意识到这可能是需要避免的强依赖。编写更少的模块当然不是解决方案,不要忘记单一职责原则。

如何解决呢?依赖反转

如果不能在一个模块内部初始化另外的模块,那么需要以其他的形式初始化这些模块。你能想象如何实现吗?没错,通过构造函数。这基本上就是依赖反转原则的涵义了。你不应该依赖具体的模块对象,应该依赖抽象。

前面的代码应该修改为:

public class Module1{
   private Module2 module2;

   public Module1(Module2 module2){
      this.module2 = module2
   }

   public void doSomething(){
      ...
      module2.doSomethingElse();
      ...
   }
}

那么什么是依赖注入呢?

你已经知道了!它通过构造函数传递依赖(注入),从而把创建模块的任务从另一个模块内部抽离出来。对象在其他地方创建,并以构造函数参数的形式传递给另一个对象。

但新问题出现了。如果我们不能在模块内部创建其他的模块,那么必须有个地方对这些模块进行初始化。另外,如果我们需要创建的模块的构造函数包含大量的依赖参数,代码将变得丑陋和难以阅读,app中将存在大量传递的对象。依赖注入正是为解决这类问题而诞生的。

什么是依赖注入器?

我们可以把它理解成app中的另一个模块,专门负责提供其他模块的实例并注入他们的依赖。这是它的基本义务。模块的创建集中于app中的一个统一的入口,我们对它有完全的控制权。

最后,什么是Dagger?

Dagger是专为低端设备设计的依赖注入器。大部分依赖注入器通过反射来创建和注入依赖。反射机制是很棒的,但在低端设备上面耗时严重,特别是在老的android版本上面。然而,Dagger使用预编译器创建工作所需的所有类。这样一来,就不需要用到反射了。Dagger相比其他依赖注入器功能稍弱,但却是效率最高的。

Dagger只是用于测试吗?

当然不是!它使得在其他app中重用你的模块变得容易,或者在相同的app中改变这些模块。想象这样一个例子:你的app在debug模式下需要从本地文件中读取数据,而在release模式下需要从服务器端API请求中获取这些数据。完全有可能通过在不同的模式下注入不同的模块来实现。

结论

我知道这篇文章有点难度,但我认为在继续下一篇文章之前,有必要把基本概念先明确好。我们已经知道什么是依赖,通过依赖反转改进了什么以及我们如何通过依赖注入器实现它。

在下一篇文章中我们会开始真正的实践操作,敬请关注!

——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人同意请勿用于商业用途,谢谢——

时间: 2024-10-11 12:22:01

Android中的依赖注入:Dagger函数库的使用(一)的相关文章

Dagger——Android上的依赖注入框架

* 你也可以去Github查看这片文章 简介 在开发程序的时候,会用到各种对象,很多对象在使用之前都需要进行初始化.例如你要操作一个SharedPreference,你需要调用getSharedPreferences(String name,int mode)来获取一个对象,然后才能使用它.而如果这个对象会在多个Activity中被使用,你就需要在每个使用的场景中都写下同样的代码.这不仅麻烦,而且增加了出错的可能.dagger的用途就是:让你不需要初始化对象.换句话说,任何对象声明完了就能直接用

SignalR中的依赖注入

什么是依赖注入? 如果你已经熟悉依赖注入可以跳过此节. 依赖注入 (DI) 模式下,对象并不为自身的依赖负责. 下边的例子是一个主动 DI. 假设你有个对象需要消息日志.你可能定义了一个日志接口: C# interface ILogger { void LogMessage(string message); } 在你的对象中,你可以创建一个 ILogger来记录消息. C# // 不用依赖注入. class SomeComponent { ILogger _logger = new FileLo

转: 理解AngularJS中的依赖注入

理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS依赖注入系统是如何运行的. Provider服务($provide) $provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务(service).服务会被叫做provider的东西来定 义,你可以使用$provide来创建一个provider.你需要使用$provide中的provider方法来定义一个provi

JavaEE开发之Spring中的依赖注入与AOP编程

一.快速创建Mava管理的Spring工程 因为本篇博客是讨论关于Spring的东西,所以我们就不创建WebApp的工程了.我们使用Spring来快速的创建一个Maven管理的工程.如下所示找到File->New->Maven Project选项来创建一个新的Maven Project,具体如下所示: 下方我们选择创建一个简单的Maven工程,跳过模板的选择.上篇博客我们在创建Maven工程时,是没有选择下方这个选项的,然后我们选择了一个WebApp的模板.而本篇博客,我们不需要WebApp的

使用APT实现Android中View的注入

个人博客 http://www.milovetingting.cn 使用APT实现Android中View的注入 前言 APT是Annotation Processing Tool的简写,通过在Java编译时期,处理注解,生成代码.APT在ButterKnife.Dagger2等框架中都有应用.下面通过使用APT,实现一个类似ButterKnife的简单的View注入的框架.(参考Jett老师的课程) ButterKnife的实现原理 既然准备实现类似ButterKnife的框架,那么我们就需要

ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】

通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最终采用何种方式提供我们所需的服务实例取决于最终选择了怎样的ServiceCallSite,而服务注册是采用的ServiceDescriptor有决定了ServiceCallSite类型的选择.我们将众多不同类型的ServiceCallSite大体分成两组,一组用来创建最终的服务实例,另一类则与生命周

ASP.NET Core中的依赖注入(2):依赖注入(DI)

参考页面: http://www.yuanjiaocheng.net/ASPNET-CORE/project-layout.html http://www.yuanjiaocheng.net/ASPNET-CORE/projectjson.html http://www.yuanjiaocheng.net/ASPNET-CORE/core-configuration.html http://www.yuanjiaocheng.net/ASPNET-CORE/core-middleware.htm

ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】

到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性.这些特性包括如何针对IServiceProvider接口提供一个ServiceProvider对象,何创建ServiceScope,以及如何提供一个服务实例的集合. 一.提供一个ServiceProvider对象 我们知道当将服务类型指定为IServiceProvider接口并调用ServiceProvider的GetService方法是,ServiceProvider对象本

ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】

本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了.如果你还对这个依赖注入系统底层的实现原理具有好奇心,可以继续阅读这一节的内容. 目录一.ServiceCallSite 二.Service 三.ServiceEntry 四.ServiceTable 五.ServiceProvider 作为DI容器的体现,ServiceProvider是ASP.NET Co