移动开发中的IoC思想

在平时的面试或者开发过程中,经常遇到一个词汇:“依赖注入”,这个其实是一个编程的高级用法,跟这个词关联的设计思想就是IoC(Inversion of Control)设计原则。

IoC中文名为控制反转,在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制,这就存在控制权的对调,所以称为控制反转。

举个形象的栗子:

假设我们设计一辆汽车:先设计轮子,然后根据轮子大小设计底盘,接着根据底盘设计车身,最后根据车身设计好整个汽车。这里就出现了一个“依赖”关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。

移动开发中的IoC思想

这样的设计看起来没问题,但是可维护性却很低。假设设计完工之后,上司却突然说根据市场需求的变动,要我们把车子的轮子设计都改大一码。这下我们就蛋疼了:因为我们是根据轮子的尺寸设计的底盘,轮子的尺寸一改,底盘的设计就得修改;同样因为我们是根据底盘设计的车身,那么车身也得改,同理汽车设计也得改——整个设计几乎都得改!

我们现在换一种思路。我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。这时候,依赖关系就倒置过来了:轮子依赖底盘, 底盘依赖车身, 车身依赖汽车。

移动开发中的IoC思想

这时候,上司再说要改动轮子的设计,我们就只需要改动轮子的设计,而不需要动底盘,车身,汽车的设计了。这就是依赖倒置原则——把原本的高层建筑依赖底层建筑“倒置”过来,变成底层建筑依赖高层建筑。高层建筑决定需要什么,底层去实现这样的需求,但是高层并不用管底层是怎么实现的。这样就不会出现前面的“牵一发动全身”的情况。

再来个栗子:

假设我们要设计一个Girl和一个Boy类,其中Girl有kiss方法,即Girl想要Kiss一个Boy。那么,我们的问题是,Girl如何能够认识这个Boy?

在我们中国,常见的MM与GG的认识方式有以下几种:

1、青梅竹马:
Girl从小就知道自己的Boy。

public class Girl {  
    void kiss(){
       Boy boy = new Boy();
    }
}

然而从开始就创建的Boy缺点就是无法在更换。并且要负责Boy的整个生命周期。如果我们的Girl想要换一个怎么办?(笔者严重不支持Girl经常更换Boy)

2、亲友介绍:
由中间人负责提供Boy来见面。

public class Girl {
    void kiss(){
       Boy boy = BoyFactory.createBoy();      
    }
}

亲友介绍,固然是好。如果不满意,尽管另外换一个好了。但是,亲友BoyFactory经常是以Singleton的形式出现,不然就是,存在于Globals,无处不在,无处不能。实在是太繁琐了一点,不够灵活。我为什么一定要这个亲友掺和进来呢?为什么一定要付给她介绍费呢?万一最好的朋友爱上了我的男朋友呢?

3、父母包办:
一切交给父母,自己不用费吹灰之力,只需要等着Kiss就好了。

public class Girl {
    void kiss(Boy boy){
       // kiss boy  
      boy.kiss();
    }
}

Well,这是对Girl最好的方法,只要想办法贿赂了Girl的父母,并把Boy交给他。那么我们就可以轻松的和Girl来Kiss了。看来几千年传统的父母之命还真是有用哦。至少Boy和Girl不用自己瞎忙乎了。

这就是IoC,将对象的创建和获取提取到外部,将自己的需求表达出去,将控制权反转,实现上层对下层的“控制”。

在实际开发过程中,肯定会涉及到类与类之间的依赖,如果直接new Object出来就会出现耦合的问题,特别是涉及到跨组件的开发,有时候一个组件的功能依赖另一个组件,但我们实际上并不太想让组件之间有过多的耦合,那么这时候IoC的思想就有很大的用处了。

参考链接:https://www.zhihu.com/question/23277575/answer/169698662
参考链接:http://www.nowamagic.net/librarys/veda/detail/393

标签:IoC, 依赖注入