IOC的概念以及简单实现的思路

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/y1962475006/article/details/81287743

IOC的概念以及简单实现的思路

what

控制反转(Inversion of Control,英文缩写为IoC)把创建对象的权利交给框架,是框架的重要特征,并非面向对象编程的专用术语。它包括依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)

以上是百度百科的内容,当然看起来官方的不得了。我们今天当然不会去扣这样的字眼。
了解重点只需要搞清楚两个问题:

  1. 谁控制谁
  2. 反转了什么
    在没有IOC之前,我们的程序应该是这样的:

Child son = new Child();

当我们需要一个名叫son的Child对象时,我们就会写程序去“new”一个,自己动手丰衣足食,没毛病,这最基本不过。这个例子中,我们或者说我们写的程序“new Child()”控制生成了一个对象,是我们手动new的。
使用IOC之后:

@某注解
Child son;
son.setXXX();
son.setYYY();

相比之前,我们不用手动new了,直接son.setXXX()竟然没有报空指针。也就是说生成一个对象的事情,交给框架去做了。

如果你还不理解这个概念,那就讲个吃货的故事:
你饿了要吃饭,以前要吃鱼要自己拿着菜单跟着做,后来有了外卖平台,自己不用做也有饭吃了,你只要在上面点这道菜,就会帮你做好,送到你家。以前是你自己动手丰衣足食,后面是别人帮你做,这个角色变化,就是对“鱼”的控制由你反转到了别人。类比过来就是,对对象的控制由我们的程序反转到了框架。

why

好像也没什么大不了。。。不就是对象的实例由自己new转成了框架生成嘛。就算我手动new又怎样。还以做鱼为例,可以清蒸、可以红烧,所以我们会抽象出一个接口:

public interface CookFish{
    void cook();
}

然后会

public class BraiseFish implement CookFish{
@Override
void cook(){
// 红烧
    }
}
public class SteamedeFish implement CookFish{
    @Override
    void cook(){
        // 清蒸
    }
}

比如有个类A先是红烧的:

public class A {
    CookFish cookFish = new BraiseFish();
    cookFish.cook();
}

然后不巧,又想改成清蒸的,那么我们就得改A这个类:

public class A {
    //CookFish cookFish = new BraiseFish();
    CookFish cookFish = new SteamedeFish();
    cookFish.cook();
}

如果还有其他做法呢?还是得改这个类。再接着,如果类A中的SteamedeFish希望有个属性叫fishType标志使用哪种鱼做,


public class SteamedeFish implement CookFish{
    FishType fishType;
    public SteamedeFish(FishType fishType){
        this.fishType = fishType;
    }
    @Override
    void cook(){
        // 
    }
}

那么类A又要改:

public class A {
    //CookFish cookFish = new BraiseFish();
    CookFish cookFish = new SteamedeFish(fishType);
    cookFish.cook();
}

如果现在有类A1、A2、A3….都像这样开始不需要构造入参,当SteamedeFish改动的时候,所有持有SteamedeFish依赖的类全都要改动。当代码庞大的时候,可能你只是想改动一个小点,但是却不得不对很多文件作出改动。这很麻烦,也很危险,因为你不知道在n多个其他的类里这个改动会不会有影响。也不符合“开-闭”的设计原则(对扩展开放对修改关闭)。
究其原因,是CookFish的生成(new的动作)是由A控制的,而IOC的思想就是,生成CookFish由框架去做。类A只需要关心cook这件事就好了,别的都由框架去做。

how

既然IOC的工作就是框架帮我们生成对象实例,那么就要从java生成对象的几个方法说起:

  1. new一个
  2. 反射
  3. 反序列化
  4. clone

后面两个使用的先决条件是,已经有一个“模版”对象,只有前两个才是从无到有生成,所以思路应该从前两个入手。

  1. new 一个,Dagger的IOC方式;
  2. 反射,Spring 的IOC方式。

猜你喜欢

转载自blog.csdn.net/y1962475006/article/details/81287743