IoC & AOP設計思想探究
前言
上周剛看Spring IOC源碼的時候,和朋友高高興興的說,依賴注入真好用...
朋友:哪裡好用?
我說:不用new對象啊。
朋友:用new也不用寫全部啊,.var 快捷鍵也不慢啊。
我說:還可以解耦啊。
朋友:解耦幹嘛?
我想了想...是哦,我解耦幹啥???不解耦我照樣用啊???我炸了,陷入自己對自己的拷問。。。
自此我開始反思我學框架的方式是不是有問題。
因為想快點學完學新的東西,所以只學怎麼用和實現原理。
知其然,不知其所以然。
所以我重新找資料學習了IOC和AOP的設計思想,寫文加深印象。
正文
框架的核心作用簡單來說就是幾個
1.降低耦合,提高可維護性
2.提取復用代碼,提高編寫代碼效率
3.功能完備,且盡量輕量化
所以我認為,Spring在設計之初,所有的想法,都是圍繞著如何更好地實現這三個需求去製作的。在理解為什麼這麼設計的時候(看下面文章的時候),把設計理念和這三個核心作用對比,就很容易發現其中的奧妙。
說到Spring就要說兩大核心,IoC和AOP
IoC
控制反轉(Inversion of Control)
IoC一般來說分兩種實現方式
DL(依賴查找)
容器中的受控對象通過容器的API來查找自己所依賴的資源和協作對象。這種方式雖然降低了對象間的依賴,但是同時也使用到了容器的API,造成了我們無法在容器外使用和測試對象。 依賴查找是一種更加傳統的IoC實現方式。
這裡是使用容器的API內部實現反射創建對象,但是這也就導致了一個重要的問題,沒有加入容器的對象如果想要使用容器里的對象怎麼辦???難道要把所有的類全部加到容器里?這顯然是不方便的,所以Spring不使用DL而用DI
DI(依賴注入)
依賴注入就是將服務注入到使用它的地方。對象只提供普通的方法讓容器去決定依賴關係,容器全權負責組件的裝配,它會把符合依賴關係的對象通過屬性(JavaBean中的setter)或者是構造子傳遞給需要的對象。
對象的創建全權交給容器負責,容器內部通過反射(類載入器)實現。
和原來的創建方式比較
原本獲取實例對象的方式是這樣的:
People bean;
bean = new Student();
那這個時候我們要做的其實是三個事情
1.創建bean的棧空間
2.創建Student實例
3.bean變數指向Student實例
使用IoC以後:
[@Autowired](選用)
People bean;
這裡就做一件事
創建bean的棧空間
那麼實例對象怎麼辦呢?讓容器控制。相當於,我給你搭一個窩,容器決定你這個窩裡放不放,放什麼
這就是控制反轉
這麼做有什麼好處呢?
正常來說,資料里都是給你說降低耦合,但是這個降低耦合度的實際作用在哪裡呢?這裡我就要說到大學那個時候學到,但是完全不理解為什麼要這麼做的一種設計模式
開閉原則(Open Closed Principle)
——對修改關閉,對拓展開放
開閉原則
Java web中開閉原則(OCP)是指軟體實體應當對擴展開放,對修改關閉。對擴展開放意味著模塊的行為是可擴展的,對於修改的封閉則是對模塊的行為進行擴展時,不必改動模塊的源代碼或者二進位代碼。遵循開閉原則開閉原則是一切設計原則的基礎,它是判斷面向對象設計是否正確的最基本的原理之一。它在軟體可用性上,非常靈活。它可以通過不斷的增加新的設計模塊滿足不斷變化的新需求!並且,由於開閉原則規定對軟體原來的模塊不要修改,因此不用擔心軟體的穩定性。如果一個軟體項目某些功能已經不符合要求了,我們可以重新開發,並且只需要將現有的功能替換掉。
關鍵:不必改動模塊的源代碼,通過不斷的增加新的設計模塊滿足不斷變化的新需求,不用擔心軟體的穩定性
這個設計理念也可以解釋為,主程序代碼一般不進行修改以保證項目的穩定性,主程序代碼對拓展功能是開放的以保證業務邏輯的靈活
夠清楚了么?不夠的話我解釋一遍
如果我是這麼寫的
People bean;
bean = new Student();
在實際需求中,如果我們對某個類需要進行修改,並且,這個類被很多其他類所依賴。那麼怎麼改呢?你是改Student類呢?還是新寫一個類再把項目所有的Student的類全改了名字呢??顯然都不合適,改Student類呢不符合開閉原則,改名字呢麻煩死了。
所以這個時候IoC就隆重登場了
People bean;
我這麼寫我根本就沒告訴你我裝的是啥,我隨時可以改我裝的東西,我只要告訴容器,不好意思,我現在該需求了,Student俺不想要你了,你先去容器里待著等著我分配崗位吧
這裡回歸三大作用之一:降低耦合,提高可維護性
那這個容器是啥?
容器就是一個管理組件的地方,把需要管理的組件放進容器里,容器會幫助你做很多很多很多很多很多很多事情。
去看Spring源碼就會知道,容器裡面有很多很多很多很多很多工廠,這些工廠幫你生產對象,再返回一個被加工過的對象還給你,所以說工廠設計模式是Spring用的最廣泛的設計模式。
順帶一提,放到容器里的對象最終會變成一張Map(String,Object)表儲存起來,用Key來取對象。
那這樣的話,我每次用容器我還要自己去搞那些工廠類么???
如果你這麼想那可太低估Spring了
這裡回歸三大作用之一 :提取復用代碼,提高編寫代碼效率
Spring希望你寫代碼越少越好,所以Spring搞了一個配置化...用XML文件去配置容器,工廠代碼幾乎看都看不見...
我們只要在XML里告訴容器什麼類叫什麼ID,什麼類存什麼東西即可,並且修改方便。
這樣嬸兒的