Android中的依赖注入

前言

最近在重构项目,用到依赖注入,查了很多资料,这里主要是记录一下自己的理解。

正文

依赖注入的优势

 1.代码的可复用性

 2.便于重构

 3.易于测试

什么是依赖注入?

 依赖注入(DI)是一种广泛的应用编程的技术,非常适合Android开发,通过遵循DI的原则,您可以为良好的应用程序架构打下基础。

类通常需要对其他类的引用,  举个例子,Car(汽车)类可能需要对Engine(引擎)类的引用。这些必需的类称为依赖项,

class Car {

    private Engine engine = new Engine();

    public void start() {
        engine.start();
    }
}


class MyApp {
    public static void main(String[] args) {
        Car car = new Car();
        car.start();
    }
}

在本例中在没有依赖注入,Car和Engine是紧密耦合的,如果现在定义一个名为ElectricEngine的新引擎类,那么Car类是不可复用的。

那么依赖注入是怎么使用的呢?与Car的每个实例在初始化时构造自己的Engine对象不同,它在构造函数中接收一个Engine对象作为参数

class Car {

    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void start() {
        engine.start();
    }
}


class MyApp {
    public static void main(String[] args) {
        Engine engine = new Engine();
        Car car = new Car(engine);
        car.start();
    }
}

Car的可复用性。你可以把不同的引擎实现传递给Car。例如,您可能定义了一个名为ElectricEngine的新引擎子类,希望Car使用它。如果您使用DI,您所需要做的就是传递一个更新后的ElectricEngine子类的实例,Car仍然可以工作,而不需要做任何进一步的更改。

在Android 中有两种主要的依赖注入方式:

1.构造函数注入(上面的例子)。这就是上面描述的方法。将类的依赖项传递给它的构造函数。

2.字段注入(或Setter注入)。某些Android框架类(比如activity和fragments)是由系统实例化的,所以构造函数注入是不可能的。   使用字段注入,依赖项在类创建后实例化。代码如下

class Car {

    private Engine engine;

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public void start() {
        engine.start();
    }
}

class MyApp {
    public static void main(String[] args) {
        Car car = new Car();
        car.setEngine(new Engine());
        car.start();
    }
}

注意:依赖项注入基于控制反转原理,其中泛型代码控制特定代码的执行

 在前面的示例中,您自己创建、提供和管理不同类的依赖项,而不依赖于库。这称为手动依赖项注入。在Car的例子中,只有一个依赖项,但是更多的依赖项和类会使依赖项的手动注入变得更加繁琐。手动依赖注入也出现了几个问题:

 对于大型应用程序,获取所有依赖项并正确地连接它们可能需要大量代码。在多层体系结构中,为了为顶层创建对象,您必须提供它下面的所有层的依赖关系,举个具体的例子,要造一辆真正的汽车,你可能需要一个发动机、一个变速器、一个底盘和其他部件;而发动机则需要气缸和火花塞。那有没有解决这个问题的方案呢?答案是:当然有了,那就是自动依赖注入。

自动依赖注入目前有两种解决方案:

1.在运行时连接依赖项的基于反射的解决方案。

2.在编译时生成连接依赖项的代码的静态解决方案。

Dagger是一个流行的Java、Kotlin和Android的依赖注入库,由谷歌维护。Dagger通过为您创建和管理依赖关系图,为您在应用程序中使用DI提供了便利。它提供了完全静态的和编译时的依赖关系,解决了许多基于反射的解决方案(如Guice)的开发和性能问题。

基于反射的解决方案我们这里不讲,我这里主要是用到的Dagger,下一篇文章我会专门讲解Dagger.

此外本文章如有什么写的不到位的地方,欢迎留言指正!!!

Android开发社区
Android开发社区

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章