美文网首页Android开发Android开发Android开发经验谈
Dagger2 简单入门三部曲(一)——是什么?

Dagger2 简单入门三部曲(一)——是什么?

作者: d74f37143a31 | 来源:发表于2018-11-27 22:07 被阅读12次

Dagger2 简单入门三部曲(一)——是什么?
Dagger2 简单入门三部曲(二)——为什么使用?(进行中)
Dagger2 简单入门三部曲(三)——怎么使用?(进行中)

Github 的介绍是:A fast dependency injector for Android and Java。(Android和Java的快速依赖注入器)

Dagger2 Github 地址

通过上边了解到依赖注入这个词,在AndroidJava中什么是依赖注入呢?

依赖注入是什么?

在软件工程领域,依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一。

上面提到控制反转这个词,那么什么是控制反转呢?

控制反转是什么?

百度百科 是这么介绍的:

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

民间通俗理解:

就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量,那么你就 new 出来用呗~~
IoC的原则是:NO,我们不要new,这样耦合度太高;你配置个 xml文件,里面标明哪个类,里面用了哪些成员变量,等待加载这个类的时候,我帮你注入(new)进去;

这里又有个问题,解耦解的谁和谁的耦?

下面来看实现一个导演名来搜索电影的代码:

public class MovieLister {
    private MovieFinder finder;
    public MovieLister() {
        // MovieFinderImpl 实现里具体的查找所有电影方法
        finder = new MovieFinderImpl();
    }
    /**
    *  根据导演名来搜索电影,返回电影集合
    *  @param arg 导演名
    */
    public Movie[] moviesDirectedBy(String arg) {
        // 获取所有电影
        List allMovies = finder.findAll();
        for (Iterator it = allMovies.iterator(); it.hasNext();) {
            Movie movie = (Movie) it.next();
            // 移除不是该导演的电影
            if (!movie.getDirector().equals(arg)) it.remove();
        }
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }
    ...
}

/**
*  抽象实现接口
*/
public interface MovieFinder {
    List findAll();
}

以上代码看起来还是很美观的,但是

当我们希望修改 finder,将finder替换为一种新的实现时(比如为MovieFinder增加一个参数表明Movie数据的来源是哪个数据库),我们不仅需要修改MovieFinderImpl类,还需要修改我们MovieLister中创建MovieFinderImpl的代码

这就是依赖注入要处理的耦合。这种在MovieLister中创建MovieFinderImpl的方式,使得MovieLister不仅仅依赖于MovieFinder这个接口,它还依赖于MovieListImpl这个实现。 这种在一个类中直接创建另一个类的对象的代码, 是一种导致耦合的方式。

那么我们如何去实现依赖注入从而达到解耦呢?

常用的有三种方式实现

  • 构造函数 注入(Contructor Injection)

继续拿上面的代码来分析,通过构造函数注入可以让MovieLister就只依赖于我们定义的MovieFinder接口,而不依赖于MovieFinder的实现了,这就减少了一个耦合。实现的代码如下:

public class MovieLister {
    private MovieFinder finder;
    public MovieLister(MovieFinder finder) {
        this.finder = finder;
    }
    ...
}
  • setter 注入

下面的实现也是减去了MovieFinderImpl的耦合

public class MovieLister {
    private MovieFinder finder;
    ...
    public void setFinder(MovieFinder finder) {
        this.finder = finder;
    }
}
  • 接口 注入

首先要创建一个注入使用的接口:

public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}

之后,我们让MovieLister实现这个接口

class MovieLister implements InjectFinder {
    private MovieFinder finder;
    ...
    public void injectFinder(MovieFinder finder) {
      this.finder = finder;
    }
    ...
}

这里贴出利用接口注入实现解耦后的完整代码:

// MovieFinder
public interface MovieFinder {
    List findAll();
}
// MovieFinderImpl 具体实现
public class MovieFinderImpl implements MovieFinder {

    private static final String TAG = "MovieFinderImpl";

    @Override
    public List findAll() {
        Log.e(TAG, "findAll: 查找所有电影");
        return new ArrayList();
    }
}

先定义一个接口
public interface InjectFinder {
    void injectFinder(MovieFinder finder);
}

实现该接口
public class MovieLister implements InjectFinder{

    private static final String TAG = "MovieLister";

    private MovieFinder finder;

    /**
     *  根据导演名来搜索电影,返回电影集合
     *  @param arg 导演名
     */
    public Movie[] moviesDirectedBy(String arg) {
        // 获取所有电影
        List allMovies = finder.findAll();
        // 简单打印语句
        Log.e(TAG, "moviesDirectedBy: 移除不是"+arg+"导演的电影" );
        return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
    }

    @Override
    public void injectFinder(MovieFinder finder) {
        this.finder = finder;
    }
}

调用:
MovieFinder movieFinder = new MovieFinderImpl();
MovieLister movieLister = new MovieLister();
// 这里通过接口注入
movieLister.injectFinder(movieFinder);
movieLister.moviesDirectedBy("张艺谋");

不出意外,运行之后会得到如下的显示结果:


这是输出的结果

参考-----依赖注入原理

综上所述

Dagger2 是一个依赖注入框架,用于实现控制反转的一种方式,主要是为了降低代码之间的耦合度。常见的依赖注入解耦方式有:构造函数注入、setter 注入、接口注入。

控制反转的实现还有另一种方式是依赖查找,这里暂时不深入研究了。

文章到这里就结束了,下篇文章介绍,为什么使用 Dagger2。

相关文章

网友评论

    本文标题:Dagger2 简单入门三部曲(一)——是什么?

    本文链接:https://www.haomeiwen.com/subject/edinqqtx.html