IOC 反轉(zhuǎn)控制
- 控制反轉(zhuǎn) 是一種思想,通俗的來(lái)講就是,把自己控制創(chuàng)建對(duì)象的權(quán)力轉(zhuǎn)交出去給一個(gè)特定的容器,自己不用直接管理對(duì)象的創(chuàng)建,只是間接的通過(guò)這個(gè)容器的拿到自己想要的對(duì)象
耦合
- 在理解IOC之前我們要去理解另一個(gè)概念,就是 耦合 ,
什么是耦合呢 ,通常我們需要通過(guò)很多類之間合作來(lái)完成一個(gè)業(yè)務(wù)邏輯 ,通常的引用方式是 通過(guò)在一個(gè)類的內(nèi)部組合另一個(gè)類的引用才能調(diào)用其內(nèi)部的功能,這樣子做確實(shí)能實(shí)現(xiàn)業(yè)務(wù),但是他們之間的必然聯(lián)系會(huì)很密切,耦合度非常的高,導(dǎo)致維護(hù)的難度很高,所以我們才會(huì)用 IOC 這種思想來(lái)降低 這種維護(hù)的難度,降低耦合度;
試著用代碼來(lái)理解:
比如一個(gè)老板去給一個(gè)工作者指派工作
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 累了 休息一下 老板就必須重新找一個(gè)來(lái)頂替工作者 所以會(huì)在內(nèi)部 又new了一個(gè)新的工作者 DomeTow,
public class DomeTow {
public void gongzuo(){
System.out.println("tow工作了");
}
}
/*老板指派任務(wù)給了 tow*/
public class Boss {
DomeTow tow=new DomeTow();
public void domeGongzuo(){
tow.gongzuo();
}
}
這樣子做的話,每次換一個(gè)人都要老板都要自己new一個(gè)新的工作者出來(lái) 沒(méi)有老板會(huì)愿意這樣子做的 那會(huì)累死。
所以他會(huì)找一個(gè)人事來(lái)幫他管理這個(gè)事情,所以他會(huì)把控制權(quán) 反轉(zhuǎn)給了人事
所以我們來(lái)做一個(gè)簡(jiǎn)單的控制反轉(zhuǎn) 當(dāng)然在這里之前你得了解多態(tài)
/*指定工作 和 判斷休息 的規(guī)范*/
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代表沒(méi)有休息 */
@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();//打印時(shí) tow在工作
}
}
*這樣子做的話 老板只需要?jiǎng)?chuàng)建人事管理者并調(diào)用它的一個(gè)方法 就不用管了 而控制創(chuàng)建工作者的權(quán)力就交給了人事者 ,當(dāng)now 休息的時(shí)候只需要人事去創(chuàng)建tow來(lái)工作 老板就可以輕松的下指令就行了,這就是控制反轉(zhuǎn) 把控制的權(quán)力反轉(zhuǎn)給一個(gè)容器 是一種編程的思想 可以使代碼降低耦合,實(shí)現(xiàn)代碼的復(fù)用
DI 依賴注入
控制反轉(zhuǎn)是一種思想 而依賴注入是一種技術(shù) 依賴注入和反轉(zhuǎn)控制是相輔相成的 是實(shí)現(xiàn)反轉(zhuǎn)控制的一種方式 那么依賴到底是什么呢? 依賴就是 當(dāng)我們 Boos 的類中就要依賴 Personnel 類 而我們的Personnel 類就要依賴 我們兩個(gè) 工作者類 ;而注入就是我們要在給他們注入他們想要的類 符合規(guī)范的類;實(shí)現(xiàn)真正意義上的解耦 實(shí)現(xiàn)代碼的可復(fù)用性;
其實(shí)依賴注入非常的簡(jiǎn)單 就是把要依賴的類的類型當(dāng)作被依賴類中的成員屬性 ,用構(gòu)造函數(shù)或者set方法去給他注入就行了!
來(lái)看看代碼
在之前的代碼 都是在類中直接new 依賴的類 我們直接用set方法給他注入
在這里我們暫時(shí)把 一個(gè)測(cè)試類 來(lái)當(dāng)作一個(gè)容器 去給他們注入想要的類 所以控制權(quán)到了容器中
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();
}
}
這樣所以的控制權(quán)都交給了測(cè)試類