Spring IOC 能降低耦合的問題分析及解決方法
有同學(xué)在學(xué)習(xí) Spring 框架中可能會(huì)問這樣的問題,為什么通過依賴注入就可以降低代碼間的耦合呢?我通過 new 生產(chǎn)對(duì)象不也可以嗎,不就是一行代碼的不同,一個(gè)是 @Resource 注入,一個(gè)是 new 創(chuàng)建,怎么就降低耦合了?
今天博主就帶大家來一步步剖析這個(gè)問題
一、傳統(tǒng)方式創(chuàng)建對(duì)象
通常我們是這樣創(chuàng)建對(duì)象的
WuliCar wuli = new WuliCar(); wuli.run();
第一天:二明想用一輛車,然后通過 new 搞了一輛五菱榮光,調(diào)用 run 方法開始使用,車子跑起來了,很高興。
一個(gè)月后:二明公司賺錢了,不想開五菱了,想換輛寶馬,接下來二明一頓操作:
BaomaCar baoma = new BaomaCar(); baoma.run();
很好,車子從五菱換成了寶馬,跑起來了,很高興。
半年后:二明公司賺大錢了,二明想搞輛直升機(jī),接下來又一頓操作
ZhiShenJi zhi = new ZhiShenJi(); zhi.fly();
這次改動(dòng)比較大,寶馬換成直升機(jī),run 換成了 fly。
看到這里先思考一下,不想往下看,這樣做有什么問題嗎?
思考時(shí)間到,我們接著往下看。
從代碼看好像沒多大問題,不就改了兩行代碼嘛,這有啥。你想想,如果你的代碼中有 1000 個(gè)地方都是這么寫的,你想把寶馬換成直升機(jī)豈不是要改 1000 次,run 改成 fly 又要改 1000 次,晚上別想下班了。
二、接口編程
經(jīng)過上次一頓操作,二明加了好幾天班才弄完,二明想想每天這么搞不得累死,不行,得想想辦法。于是二明腦子一轉(zhuǎn)了,一想就想到了。我定義好一些方法,大家都按照這個(gè)規(guī)則來,不就好了。
public interface vehicle {
// 定義一個(gè)交通工具接口,有一個(gè) work 方法
void work();
}寶馬實(shí)現(xiàn)這個(gè)接口:
public class Baoma implements vehicle {
@Override
public void work() {
System.out.println("寶馬跑起來");
}
}
飛機(jī)實(shí)現(xiàn)這個(gè)接口:
public class ZhiShenJi implements vehicle {
@Override
public void work() {
System.out.println("直升機(jī)飛起來");
}
}
經(jīng)過上面改造后,后面二明想把寶馬換成直升機(jī)的時(shí)候只需要修改 new 那塊就可以了,省了很多時(shí)間
三、工廠方法
利用接口確實(shí)好一些了,但是問題還是沒有解決。為了提高內(nèi)聚性,專職類負(fù)責(zé)特定的事情,所以我們使用一個(gè)類作為工廠類,既能生產(chǎn) Car 又能生產(chǎn) 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;
}
}
如果有一次我想鍛煉身體,想騎自行車了,那么很簡(jiǎn)單
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();
這種方法把創(chuàng)建對(duì)象的過程交給了一個(gè)專業(yè)的類(Factory),我只需要告訴他我需要什么(參數(shù)),他就會(huì)返回給我正確的對(duì)象,只是解決了內(nèi)聚性的問題,但是他并沒有解決我的聲明語句七零八落的散落在程序中,我還是需要去將參數(shù)從car替換為zixingche
四、反射
后來二明想到一個(gè)更絕妙的主意.我在寫程序的時(shí)候不告訴工廠我需要什么,等到運(yùn)行的時(shí)候我再告訴工廠我需要什么,再利用反射技術(shù)給我生產(chǎn)出來不就可以了嗎?二明說干就干
Vehicle vehicle = VehicleFactory.getInstance(讀取配置文件); vehicle.work(); 我想要的:zixingche zixingche.work();
大功告成,這樣我要什么,都寫在一個(gè)配置文件中,利用反射技術(shù)就可以創(chuàng)建好,這樣我就不用在生產(chǎn)了,下次換車的時(shí)候直接去配置文件中修改就好了,代碼中不用修改。
對(duì)于生產(chǎn)對(duì)象這件和業(yè)務(wù)沒有直接關(guān)系的事情,我們已經(jīng)提取給了專業(yè)的工廠,專業(yè)的工廠還是根據(jù)配置文件進(jìn)行的生產(chǎn),想生產(chǎn)什么我只需要改一處即可,這就是降低了耦合性(生產(chǎn)對(duì)象和業(yè)務(wù)之間的耦合,讓生產(chǎn)對(duì)象對(duì)業(yè)務(wù)的影響降到了最低)。
五、Spring IOC
上面第四點(diǎn)說的那些功能,Spring IOC 已經(jīng)幫助我們實(shí)現(xiàn)了,Spring IOC 就是利用工廠模式+反射實(shí)現(xiàn)自動(dòng)生產(chǎn)對(duì)象,管理對(duì)象生命周期的功能。降低了代碼的耦合
總結(jié)
- 依賴注入的意思是你需要的東西不是由你創(chuàng)建的,而是第三方,或者說容器提供給你的。這樣的設(shè)計(jì)符合正交性,即所謂的松耦合。
- 依賴注入是調(diào)用者僅通過聲明某個(gè)組件就可以獲得組件的控制權(quán),而對(duì)該組件的依賴關(guān)系管理、查找、加載由外部完成。
- 依賴注入就是你不用關(guān)心對(duì)象的生命周期,什么時(shí)候被創(chuàng)建,什么時(shí)候銷毀,只需直接使用即可,對(duì)象的生命周期由提供依賴注入的框架來管理。
到此這篇關(guān)于Spring IOC 為什么能降低耦合的文章就介紹到這了,更多相關(guān)Spring IOC 降低耦合內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
由淺到深帶你詳談Java實(shí)現(xiàn)數(shù)組擴(kuò)容的三種方式
這篇文章主要詳細(xì)介紹了Java實(shí)現(xiàn)數(shù)組擴(kuò)容的三種方式,新建一個(gè)數(shù)組,把原來數(shù)組的內(nèi)容搬到新數(shù)組中,使用system.arraycopy(),使用java.util.Arrays.copyOf()這三種方式,具有一定的參考價(jià)值,需要的朋友可以借鑒一下2023-06-06
java設(shè)計(jì)模式學(xué)習(xí)之工廠方法模式
這篇文章主要介紹了java設(shè)計(jì)模式學(xué)習(xí)之工廠方法模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
java開發(fā)gui教程之jframe監(jiān)聽窗體大小變化事件和jframe創(chuàng)建窗體
這篇文章主要介紹了java開發(fā)gui教程中jframe監(jiān)聽窗體大小變化事件和jframe創(chuàng)建窗體的示例,需要的朋友可以參考下2014-03-03
java將一個(gè)整數(shù)轉(zhuǎn)化成二進(jìn)制代碼示例
這篇文章主要介紹了java將一個(gè)整數(shù)轉(zhuǎn)化成二進(jìn)制代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12
SpringBoot如何根據(jù)目錄路徑生成接口的url路徑
這篇文章主要介紹了SpringBoot如何根據(jù)目錄路徑生成接口的url路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
javaweb servlet中使用請(qǐng)求轉(zhuǎn)發(fā)亂碼的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄猨avaweb servlet中使用請(qǐng)求轉(zhuǎn)發(fā)亂碼的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
SpringCloud基本Rest微服務(wù)工程搭建過程
這篇文章主要介紹了SpringCloud基本Rest微服務(wù)工程搭建,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

