下面经过两张简单的图,了解一下控制反转的思想,咱们假设本身如今想吃回锅肉!编程
首先,咱们能够本身炒一道符合本身口味的回锅肉,能够多加肉!而后咱们就把它吃掉!!这种状况下回锅肉炒成什么样由咱们本身控制。网络
ok!次日咱们又想吃回锅肉了,可是有点懒,咱们选择点外卖。单元测试
这回咱们叫的外卖,那么商家将回锅肉炒成什么样并非咱们能决定的,也就是回锅肉炒成什么样不是咱们可以控制的,咱们就是拿到外卖吃。测试
很明显回锅肉的控制权从本身变成了别人,这种就叫作控制反转。code
在面向对象编程中,每当咱们要new一个新的对象的时候,也就是咱们所说的实例化对象,通常状况下都是主动new一个新的对象。在IOC思想中,咱们一般把实例化的任务交给别人,也就是本身主动的实例化变为被动的实例化,本身对实例的控制权被别人替代了,即控制权反转了。咱们通常将实例化的任务交给IOC容器统一管理生命周期。对象
依赖注入是实现控制反转思想的一种方式,其想法就是在对象或属性被初始化的时候,将它所须要的依赖从外部注入进来,并不须要本身内部实例化依赖。blog
咱们经过一段代码(Go语言)来看看为何注入的依赖符合控制反转的思想。接口
type Player struct { name string } type GameRoom struct { player *Player } //这里咱们就将GameRoom依赖的Player从外部注入进来 //Player的实例化也交给了外部,因此对于Player的控制权反转了。 func NewGameRoom(player *Player) *GameRoom { return &GameRoom{player: player} }
不少状况下咱们会使用接口注入,而接口的实例化就归外部(一般是IOC容器),不只符合多态,更加体现了依赖倒置原则(双方都应该依赖一个抽象)。生命周期
type Player interface { GetName() string } type GameRoom struct { player Player } //Player经过接口的方式注入进来,咱们无须 //关系Player如何实现的,这样连注入的依赖 //也变成抽象的 func NewGameRoom(player Player) *GameRoom { return &GameRoom{player: player} }
这种方式好处颇多,好比更容易被单元测试、代码耦合性下降等等等等。但愿这篇最简单的解释,可以使咱们更快地理解IOC和DI的概念。string