- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Java基礎之教你如何正確運用依賴(lài)注入
C++最遭人詬病的地方就是定義一個(gè)類(lèi)需要寫(xiě)兩個(gè)文件,一個(gè).h文件和一個(gè).cpp文件。例如定義一個(gè)CMainFrame類(lèi),mainframe.h內容如下:
class CMainFrame : public CFrameWndEx { protected: CMainFrame(); public: virtual ~CMainFrame(); };
mainframe.cpp內容如下:
CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame() { }
當需要給這個(gè)類(lèi)添加一個(gè)方法時(shí),需要同時(shí)修改.h文件和.cpp文件。例如新增一個(gè)DefWindowProc函數。需要在.h文件中增加該函數的聲明。
class CMainFrame : public CFrameWndEx { protected: CMainFrame(); public: virtual ~CMainFrame(); protected: virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); };
mainframe.cpp中增加DefWindowProc的定義:
LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if(message==WM_NCPAINT ) { if(bShow){ ShowWindow(SW_SHOW); } else { ShowWindow(SW_HIDE); } } return CFrameWndEx::DefWindowProc(message, wParam, lParam); }
可以看出C++的類(lèi)定義代碼中,一次變化需要修改兩個(gè)文件,其維護的繁瑣令人詬病。
然而Java的出現徹底解決了這個(gè)問(wèn)題,一個(gè)類(lèi)就對應一個(gè).java文件(包括后來(lái)其他面向對象語(yǔ)言也秉承了這個(gè)思路,比如C#)。
比如一個(gè)LogService類(lèi)用于對日志進(jìn)行維護,起初只包含日志的增刪功能,LogService.java代碼如下。
public class LogService{ public ServiceResult<Boolean> addLog (SysLogInfo logInfo) { ...... } public ServiceResult<Boolean> delLog (String id) { ...... } }
當需要增加一個(gè)updateLog方法時(shí),僅需對LogService.java進(jìn)行修改。
public class LogService{ public ServiceResult<Boolean> addLog (SysLogInfo logInfo) { ...... } public ServiceResult<Boolean> delLog(String id) { ...... } public ServiceResult<Boolean> updateLog (SysLogInfo logInfo) { ...... } }
一切變得方便了很多。
但是最近在看一些基于Spring(SpringBoot、SpringMVC)框架寫(xiě)的代碼時(shí),發(fā)現很多類(lèi)的代碼又回到了C++的形式。例如在使用一個(gè)LogService時(shí),開(kāi)發(fā)人員首先定義了一個(gè)interface,在LogService.java中:
public interface LogService { ServiceResult<Boolean> addLog(SysLogInfo logInfo); ServiceResult<Boolean> delLog(String id); }
然后定義了一個(gè)該接口的實(shí)現類(lèi),在LogServiceImpl.java中:
public class LogServiceImpl implements LogService{ @Override public ServiceResult<Boolean> addLog(SysLogInfo logInfo) { ...... } @Override public ServiceResult<Boolean> delLog(String id) { ...... } }
在需要實(shí)例化這個(gè)類(lèi)的地方用了一個(gè)@Autowired注解注入。
public class LogController { @Autowired private LogService logservice; }
在問(wèn)及開(kāi)發(fā)人員為什么要象這樣做時(shí),其給了一個(gè)自信的回答:這是面向接口編程!
注意:這個(gè)設計中LogService.java類(lèi)似于C++中的.h文件,LogServiceImpl.java類(lèi)似于C++中的.cpp文件,這兩個(gè)文件共同定義了一個(gè)LogService類(lèi)。當需要給這個(gè)類(lèi)添加一個(gè)updateLog方法時(shí),LogService.java和LogServiceImpl.java都需要被修改,又走回了C++的老路。這顯然是對面向接口編程的曲解。如果這樣都能算面向接口編程的話(huà),那么C++就成了一門(mén)天然的面向接口編程的語(yǔ)言,還何必去學(xué)那些復雜的設計模式。
不過(guò)這樣寫(xiě)代碼有什么問(wèn)題嗎?其實(shí)也沒(méi)有太大問(wèn)題,只是代碼繁瑣一點(diǎn)而已(C++就是這樣的)。只不過(guò)既然你選擇了Java語(yǔ)言,卻又寫(xiě)成了C++的樣子,就好像在開(kāi)一輛自動(dòng)擋的汽車(chē),卻一直撥到手動(dòng)模式駕駛一樣。
那么什么才是面向接口編程呢,其要點(diǎn)在于:接口是基于變化的抽象。在有可能變化的地方才需要接口。假設上面的例子中,寫(xiě)日志的動(dòng)作同時(shí)存在3種不同的實(shí)現:
1.寫(xiě)到日志文件。
3.寫(xiě)到本地的一個(gè)日志服務(wù)的UDP端口。
那么可以基于這個(gè)接口寫(xiě)3個(gè)不同的實(shí)現類(lèi):
public class LogServiceFile implements LogService{ }
public class LogServiceDB implements LogService{ }
public class LogServiceUdp implements LogService{ }
當然此時(shí)如果還是使用下面的代碼會(huì )報錯,因為Autowired只能裝配對應接口的唯一一個(gè)派生類(lèi)的Bean,而此時(shí)存在3個(gè)派生類(lèi)。
public class LogController { @Autowired private LogService logservice; }
需要改進(jìn)成類(lèi)似下面這個(gè)樣子,根據實(shí)際情況使用對應的派生類(lèi)對象:
public class LogController { private LogService logservice; void writeLog(SysLogInfo logInfo){ logservice = GetLogServiceInst(); logservice.addLog(logInfo); } }
如果你的接口只有一個(gè)實(shí)現類(lèi),而且在可以遇見(jiàn)的將來(lái)也不會(huì )有其他實(shí)現類(lèi),那么還是建議你能簡(jiǎn)化一點(diǎn),采用最基本的類(lèi)定義方式,減少代碼的復雜性。
到此這篇關(guān)于教你如何正確運用Java依賴(lài)注入的文章就介紹到這了,更多相關(guān)Java依賴(lài)注入內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站