美文网首页
浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

作者: 勇敢地追 | 来源:发表于2019-05-23 15:33 被阅读0次

1.什么是依赖(Dependency)?

依赖是一种关系,通俗来讲就是一种需要。
比如

class Shopper {
    FoodA mFoodA;
    public Shopper() {
        mFoodA = new FoodA();
    }
}

Shopper 的内部持有 FoodA 的引用,这就是依赖在编程世界中的体现。

2.依赖倒置(DIP)

定义

  • 上层模块不应该依赖底层模块,它们都应该依赖于抽象。
  • 抽象不应该依赖于细节,细节应该依赖于抽象。
    还是以上面的商家拥有食物的例子来说.通常一个商家不止一种,可能还有FoodB
class Shopper {
    //FoodA mFoodA;
    FoodB mFoodB;
    public Shopper() {
        //mFoodA = new FoodA();
        mFoodB = new FoodB();
    }
}

甚至会有FoodC,FoodD等等.问题是每次我们都要去改Shoper类么?当然不是,我们可以引入抽象

interface Food {
    void printFoodName();
}

class FoodA implements Food {
    @Override
    public void printFoodName() {
        System.out.println("FoodA");
    }
}

class FoodB implements Food {
    @Override
    public void printFoodName() {
        System.out.println("FoodB");
    }
}

这样一来,Shopper就简单多了(当然,此时还是需要改动的)

class Shopper {
    Food mFood;
    public Shopper() {
        mFood = new FoodB();// 想要哪种就配哪种
    }
    public void print() {
        mFood.printFoodName();
    }
}

3.控制反转 (IoC)

控制权放外面(本来由Shopper来决定Food的种类,现在可以放在外面,让业务来决定)这样一来,就算Food种类有变化,依然不需要去改Shopper的代码
显然,上面的例子还没做到

4.依赖注入(Dependency injection)

依赖注入,也经常被简称为 DI,它是一种实现 IoC 的手段。
实现依赖注入有 3 种方式:

1.构造函数中注入
class Shopper {
    Food mFood;
    public Shopper(Food food) {
        mFood = food;
    }
    public void print() {
        mFood.printFoodName();
    }
}

优点:在 Shopper 一开始创建的时候就确定好了依赖。
缺点:后期无法更改依赖。

2.setter 方式注入
class Shopper {
    Food mFood;
    public void setFood(Food food) {
        mFood = food;
    }
    public void print() {
        if(mFood != null) {
            mFood.printFoodName();
        }
    }
}

优点:Shopper 对象在运行过程中可以灵活地更改依赖。
缺点:Shopper 对象运行时,可能会存在依赖项为 null 的情况,所以需要检测依赖项的状态。

3. 接口注入
interface Owner {
    void setFood(Food food);
}
class Shopper implements Owner {
    Food mFood;

    @Override
    public void setFood(Food food) {
        mFood = food;
    }

    public void print() {
        if(mFood != null) {
            mFood.printFoodName();
        }
    }
}

和set注入很像?那么加入一个接口是不是多此一举呢?
答案肯定是不是的,这涉及到一个角色的问题。除了Shopper可以设置food以外,顾客也可以选择food啊
接口的存在,表明了一种依赖配置的能力。

参考文章

https://blog.csdn.net/a8688555/article/details/78792793

相关文章

网友评论

      本文标题:浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)

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