Spring IOC 能降低耦合的問題分析及解決方法
有同學在學習 Spring 框架中可能會問這樣的問題,為什麼通過依賴註入就可以降低代碼間的耦合呢?我通過 new 生產對象不也可以嗎,不就是一行代碼的不同,一個是 @Resource 註入,一個是 new 創建,怎麼就降低耦合瞭?
今天博主就帶大傢來一步步剖析這個問題
一、傳統方式創建對象
通常我們是這樣創建對象的
WuliCar wuli = new WuliCar(); wuli.run();
第一天:二明想用一輛車,然後通過 new 搞瞭一輛五菱榮光,調用 run 方法開始使用,車子跑起來瞭,很高興。
一個月後:二明公司賺錢瞭,不想開五菱瞭,想換輛寶馬,接下來二明一頓操作:
BaomaCar baoma = new BaomaCar(); baoma.run();
很好,車子從五菱換成瞭寶馬,跑起來瞭,很高興。
半年後:二明公司賺大錢瞭,二明想搞輛直升機,接下來又一頓操作
ZhiShenJi zhi = new ZhiShenJi(); zhi.fly();
這次改動比較大,寶馬換成直升機,run 換成瞭 fly。
看到這裡先思考一下,不想往下看,這樣做有什麼問題嗎?
思考時間到,我們接著往下看。
從代碼看好像沒多大問題,不就改瞭兩行代碼嘛,這有啥。你想想,如果你的代碼中有 1000 個地方都是這麼寫的,你想把寶馬換成直升機豈不是要改 1000 次,run 改成 fly 又要改 1000 次,晚上別想下班瞭。
二、接口編程
經過上次一頓操作,二明加瞭好幾天班才弄完,二明想想每天這麼搞不得累死,不行,得想想辦法。於是二明腦子一轉瞭,一想就想到瞭。我定義好一些方法,大傢都按照這個規則來,不就好瞭。
public interface vehicle { // 定義一個交通工具接口,有一個 work 方法 void work(); }
寶馬實現這個接口:
public class Baoma implements vehicle { @Override public void work() { System.out.println("寶馬跑起來"); } }
飛機實現這個接口:
public class ZhiShenJi implements vehicle { @Override public void work() { System.out.println("直升機飛起來"); } }
經過上面改造後,後面二明想把寶馬換成直升機的時候隻需要修改 new 那塊就可以瞭,省瞭很多時間
三、工廠方法
利用接口確實好一些瞭,但是問題還是沒有解決。為瞭提高內聚性,專職類負責特定的事情,所以我們使用一個類作為工廠類,既能生產 Car 又能生產 ZhiShenJi
class VehicleFactory{ VehicleFactory(){} public static Vehicle getInstance(String type){ Animal result = null; if("car".equals(type)){ result = new Car(); } if("zhishenji".equals(type)){ result = new ZhiShenJi(); } return result; } }
如果有一次我想鍛煉身體,想騎自行車瞭,那麼很簡單
class VehicleFactory{ VehicleFactory(){} public static Vehicle getInstance(String type){ Animal result = null; if("car".equals(type)){ result = new Car(); } if("zhishenji".equals(type)){ result = new ZhiShenJi(); } if("zixingche".equals(type)){ result = new ZiXingChe(); } return result; } }
Vehicle vehicle = VehicleFactory.getInstance("zixingche"); vehicle.work();
這種方法把創建對象的過程交給瞭一個專業的類(Factory),我隻需要告訴他我需要什麼(參數),他就會返回給我正確的對象,隻是解決瞭內聚性的問題,但是他並沒有解決我的聲明語句七零八落的散落在程序中,我還是需要去將參數從car
替換為zixingche
四、反射
後來二明想到一個更絕妙的主意.我在寫程序的時候不告訴工廠我需要什麼,等到運行的時候我再告訴工廠我需要什麼,再利用反射技術給我生產出來不就可以瞭嗎?二明說幹就幹
Vehicle vehicle = VehicleFactory.getInstance(讀取配置文件); vehicle.work(); 我想要的:zixingche zixingche.work();
大功告成,這樣我要什麼,都寫在一個配置文件中,利用反射技術就可以創建好,這樣我就不用在生產瞭,下次換車的時候直接去配置文件中修改就好瞭,代碼中不用修改。
對於生產對象這件和業務沒有直接關系的事情,我們已經提取給瞭專業的工廠,專業的工廠還是根據配置文件進行的生產,想生產什麼我隻需要改一處即可,這就是降低瞭耦合性(生產對象和業務之間的耦合,讓生產對象對業務的影響降到瞭最低)。
五、Spring IOC
上面第四點說的那些功能,Spring IOC 已經幫助我們實現瞭,Spring IOC 就是利用工廠模式+反射實現自動生產對象,管理對象生命周期的功能。降低瞭代碼的耦合
總結
- 依賴註入的意思是你需要的東西不是由你創建的,而是第三方,或者說容器提供給你的。這樣的設計符合正交性,即所謂的松耦合。
- 依賴註入是調用者僅通過聲明某個組件就可以獲得組件的控制權,而對該組件的依賴關系管理、查找、加載由外部完成。
- 依賴註入就是你不用關心對象的生命周期,什麼時候被創建,什麼時候銷毀,隻需直接使用即可,對象的生命周期由提供依賴註入的框架來管理。
到此這篇關於Spring IOC 為什麼能降低耦合的文章就介紹到這瞭,更多相關Spring IOC 降低耦合內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 一篇文章帶你深入瞭解Java對象與Java類
- 深入瞭解Spring控制反轉IOC原理
- Java中的對象、類、抽象類、接口、繼承之間的聯系
- Java工廠模式的深入瞭解
- Java面向對象基礎知識之封裝,繼承,多態和抽象