IOC 反转控制
- 控制反转 是一种思想,通俗的来讲就是,把自己控制创建对象的权力转交出去给一个特定的容器,自己不用直接管理对象的创建,只是间接的通过这个容器的拿到自己想要的对象
耦合
- 在理解IOC之前我们要去理解另一个概念,就是 耦合 ,
什么是耦合呢 ,通常我们需要通过很多类之间合作来完成一个业务逻辑 ,通常的引用方式是 通过在一个类的内部组合另一个类的引用才能调用其内部的功能,这样子做确实能实现业务,但是他们之间的必然联系会很密切,耦合度非常的高,导致维护的难度很高,所以我们才会用 IOC 这种思想来降低 这种维护的难度,降低耦合度;
试着用代码来理解:
比如一个老板去给一个工作者指派工作
public class DomeNoe {
public void gongzuo(){
System.out.println("Noe工作了");
}
}
/*老板 指派工作*/
public class Boss{
DomeNoe noe=new DomeNoe();
//
public void domeGongzuo(){
noe.gongzuo();
}
}
直接在 Boss 中 new 了 DomeNoe
有一天DomeNoe 累了 休息一下 老板就必须重新找一个来顶替工作者 所以会在内部 又new了一个新的工作者 DomeTow,
public class DomeTow {
public void gongzuo(){
System.out.println("tow工作了");
}
}
/*老板指派任务给了 tow*/
public class Boss {
DomeTow tow=new DomeTow();
public void domeGongzuo(){
tow.gongzuo();
}
}
这样子做的话,每次换一个人都要老板都要自己new一个新的工作者出来 没有老板会愿意这样子做的 那会累死。
所以他会找一个人事来帮他管理这个事情,所以他会把控制权 反转给了人事
所以我们来做一个简单的控制反转 当然在这里之前你得了解多态
/*指定工作 和 判断休息 的规范*/
public interface Gongzuo {
void gongzuo();
boolean isXiuxi();
}
public class DomeNoe implements Gongzuo{
@Override
public void gongzuo() {
System.out.println("noe在工作");
}
//判断是否休息
@Override
public boolean isXiuxi() {
return true;
}
}
/*tow*/
public class DomeTow implements Gongzuo{
@Override
public void gongzuo() {
System.out.println("tow在工作");
}
/*false代表没有休息 */
@Override
public boolean isXiuxi() {
return false;
}
}
/*人事管理者*/
public class Personnel {
private Gongzuo gongzuozhe;
public void getDome(){
gongzuozhe =new DomeNoe();
/*判断是否休息 */
if (!gongzuozhe.isXiuxi()){
gongzuozhe.gongzuo();
return;
}
gongzuozhe=new DomeTow();
if(!gongzuozhe.isXiuxi()){
gongzuozhe.gongzuo();
return;
}
System.out.println("工作者都休息了!");
}
}
/*老板*/
public class Boss {
private Personnel personnel;
public void gongZuoBa(){
personnel=new Personnel();
personnel.getDome();
}
public static void main(String[] args) {
new Boss().gongZuoBa();//打印时 tow在工作
}
}
*这样子做的话 老板只需要创建人事管理者并调用它的一个方法 就不用管了 而控制创建工作者的权力就交给了人事者 ,当now 休息的时候只需要人事去创建tow来工作 老板就可以轻松的下指令就行了,这就是控制反转 把控制的权力反转给一个容器 是一种编程的思想 可以使代码降低耦合,实现代码的复用
DI 依赖注入
控制反转是一种思想 而依赖注入是一种技术 依赖注入和反转控制是相辅相成的 是实现反转控制的一种方式 那么依赖到底是什么呢? 依赖就是 当我们 Boos 的类中就要依赖 Personnel 类 而我们的Personnel 类就要依赖 我们两个 工作者类 ;而注入就是我们要在给他们注入他们想要的类 符合规范的类;实现真正意义上的解耦 实现代码的可复用性;
其实依赖注入非常的简单 就是把要依赖的类的类型当作被依赖类中的成员属性 ,用构造函数或者set方法去给他注入就行了!
来看看代码
在之前的代码 都是在类中直接new 依赖的类 我们直接用set方法给他注入
在这里我们暂时把 一个测试类 来当作一个容器 去给他们注入想要的类 所以控制权到了容器中
package com.company.IOC;
/*老板*/
public class Boss {
private Personnel personnel;
public Boss(){}
public Boss(Personnel personnel) {
this.personnel = personnel;
}
public Personnel getPersonnel() {
return personnel;
}
public void setPersonnel(Personnel personnel) {
this.personnel = personnel;
}
public void gongZuoBa(){
personnel.getDome();
}
}
package com.company.IOC;
/*人事管理者*/
public class Personnel {
private Gongzuo gongzuozhe;
public Personnel(){
}
public Personnel(Gongzuo gongzuozhe){
this.gongzuozhe=gongzuozhe;
}
public Gongzuo getGongzuozhe() {
return gongzuozhe;
}
public void setGongzuozhe(Gongzuo gongzuozhe) {
this.gongzuozhe = gongzuozhe;
}
public void getDome(){
/*判断是否休息 */
if (!gongzuozhe.isXiuxi()){
gongzuozhe.gongzuo();
return;
}
System.out.println("该工作者都去休息了");
}
}
package com.company.IOC;
public class DomeTest {
public static void main(String[] args) {
DomeNoe noe=new DomeNoe();
DomeTow tow=new DomeTow();
Personnel personnel=new Personnel();
personnel.setGongzuozhe(tow);
Boss boss =new Boss(personnel);
boss.gongZuoBa();
}
}
这样所以的控制权都交给了测试类