IOC控制反转理解
1. IOC基礎
IOC:全稱Inversion Of Control,中文翻譯是控制反轉的意思。初學Spring繞不過去的一個彎,需要好好理解IOC的思想。網上看了很多博客,也看了很多網課,但是還是云里云霧。終于看到一個容易理解的例子,寫下自己對IOC的理解。
2. IOC推導與理解
首先編寫一個基本的項目,結構如下:
有一個Meizi(妹子)接口,里面有一個方法describe。
編寫四個類(四種類型的妹子):Yujie(御姐)、Luoli(蘿莉)、Xuemei(學妹)、NvWang(女王)類實現Meizi接口,重寫describe方法。
一個Nan(男生)接口,里面有一個方法getMeizi。
編寫兩個類:yihao(一號男生)、erhao(二號男生)實現Nan接口,重寫getMeizi方法。
為了簡單方便將所有的類實現都放在一個代碼塊中,這里利用男生找對象的方式進行理解IOC的含義。
2.1、最基本的實現方式
interface Meizi {public void describe(); }class Yujie implements Meizi{@Overridepublic void describe() {System.out.println("御姐~");} }//這里只列出一種女生類型的具體實現,其他的類似interface Nan {public void getMeizi(); }class yihao implements Nan{@Overridepublic void getMeizi() {Meizi meizi = new Yujie();meizi.describe();} }class erhao implements Nan{@Overridepublic void getMeizi() {Meizi meizi = new Yujie();meizi.describe();} }
現在整個實現是上圖所示,getMeizi方法內部依賴四種類型的妹子。
很容易看到這種設計方式違背了OOP的設計原則,至少違背了迪米特法則。我們不應該將一個陌生類(接口)作為局部變量!
沒有改動的余地,現在男生都想找一個御姐對象,如果需求變更男生想找一個女王呢?是不是需要更改所有男生的代碼?
2.2、采用組合的方式實現
假設男生最開始都有一個御姐類型的女朋友
interface Meizi {public void describe(); }class Yujie implements Meizi{@Overridepublic void describe() {System.out.println("御姐~");} }//這里只列出一種女生類型的具體實現,其他的類似interface Nan {public void getMeizi(); }class yihao implements Nan{private Meizi meizi = new Yujie();@Overridepublic void getMeizi() {meizi.describe();} } class erhao implements Nan{private Meizi meizi = new Yujie();@Overridepublic void getMeizi() {meizi.describe();} } public class Main {public static void main(String[] args) {yihao man1 = new yihao(); man1.getMeizi();erhao man2 = new erhao();man2.getMeizi();} }
采用組合關系之后如上圖,現在真正的問題來了:
組合關系:什么是組合關系?誰也離不開誰、二者之間是一個整體;比如:腦袋和身體這種關系;叫組合關系。
男一號、男二號能保證自己以后一定會跟御姐妹子走到最后嗎?或者說二者之間一定不會分手嗎?組合關系限定死了男一號、男二號更換對象的權利,他們沒有權利在更換對象了!當然御姐妹子也沒有權利更換男朋友了!
如果想跟換對象是需要重新去修改源代碼,重新new一個對象。
這個代碼設計也不好,男生、女生都喪失了更換對象的權利。耦合度太高了,硬生生的將兩個人綁在了一起。
2.3、采用聚合方式(松耦合)
組合方式限定死了男生的對象、沒有辦法更換。現在將組合方式改為聚合,不在內部直接new一個確定的對象(主動創建)。而是通過set方法給男生一個女朋友(被動接受)。
interface Meizi {public void describe(); }class Yujie implements Meizi{@Overridepublic void describe() {System.out.println("御姐~");} }//這里只列出一種女生類型的具體實現,其他的類似interface Nan {public void getMeizi(); }class yihao implements Nan{private Meizi meizi;public void setMeizi(Meizi meizi) {this.meizi = meizi;}@Overridepublic void getMeizi() {meizi.describe();} } class erhao implements Nan{private Meizi meizi;public void setMeizi(Meizi meizi) {this.meizi = meizi;}@Overridepublic void getMeizi() {meizi.describe();} }public class Main {public static void main(String[] args) {yihao man1 = new yihao();man1.setMeizi(new Yujie());man1.getMeizi();erhao man2 = new erhao();man2.setMeizi(new Luoli());man2.getMeizi();} }
通過set注入方式就可以實現解耦。
假定IOC是一個婚介所,現在男女生都婚介所登記資料,男生告訴IOC需要什么樣的對象,IOC就給男生一個。
由男生主動搭訕妹子尋找對象(new),演變成了被動的由婚介所介紹對象(set注入)!
到此IOC就是大概一個這樣的概念:控制反轉,反轉的是創建對象的方式,由主動化為被動的一個過程。
3. IOC總結
控制 : 誰來控制對象的創建 , 傳統應用程序的對象是由程序本身控制創建的 , 使用Spring后 , 對象是由Spring的IOC容器來創建的
反轉 : 程序本身不創建對象 , 而變成被動的接收對象 .
總結
- 上一篇: 了解Infiniband和RDMA技术
- 下一篇: ASP.NET MVC Areas 区域