廣大程序猿同胞,經常會看到“解耦合”,也有很多人,會用這個詞來裝X,但是,實際真正能理解的人,並不多。接下來,帶大家深入淺出的走一遍,如何解耦合。
首先,我們要知道,爲什麼要解耦合:通常,我們做一個項目,會用到很多基礎功能塊,比如xxx通信協議,xxxView等等,我們會把這種功能塊封裝成一個庫,如果這個庫,只能在這個指定的項目運行,這就叫高耦合,這就導致了,如果下次再次遇到一個類似的項目,需要用到同樣功能的功能塊時,你會要做很多重複工作。假設,每次使用json時,你都要對json庫進行改造,那將會是一個晴天霹靂。
但是,事與願違,有些情況,還真的不太好解耦。
這裏,我們先舉個栗子,比如排序。
一個排序功能,對於大部分比較初級的程序猿來說,可能會寫成這樣:
sort(List<Integer> list)
這樣就導致了一個問題所在,這個方法只能排序 int 型數據,如果下一個項目,需要用到對 String 進行排序,那就很尷尬,感覺明明要成功了,但是又差一點。對,就是差這一點,就是代碼解耦的關鍵。
我們先要明確,我們需要做的是排序功能,在這個過程中,我們不可避免的需要使用 2 個數據的大小對比,而這個數據,可能是任何數據,也就是說,排序算法,我們是可以確定下來,做成不動的庫,但是有一個數據大小匹配是我們無法做到的,或者說是庫的耦合點,那怎麼辦呢?
我們就讓使用我們這個功能塊的人,告訴我們就行啦。
下面,我們參考 Android 庫裏面,有個排序的 api
Collections.sort(List<T> list, Comparator<? super T> c);
這裏,Comparator這個接口,就是使用者,需要實現,並且傳遞進去的接口。這樣做,這個排序功能塊就可以應用在任何場合,達到一次開發,受用終身的目的。是不是很神奇?
我們再舉個栗子,socket
我們在開發時,經常會用到socket庫,而socket最常用,最常用的一個功能就是:“連接->發送數據->接收數據->斷開連接->回調結果”
所以,如果需要把這個流程,封裝成一個功能塊是很有意義的。
但是,這裏有一個問題,是阻礙封裝的,就是 “接收數據->斷開連接”,socket讀取數據時,是一個inputStream,是個流,也就是說,其實,你並不知道,數據怎麼樣纔算接收 完整/完畢
可能,有的協議,是通過頭2個字節來判斷整個數據長度
可能,有的協議是有幀頭,幀尾,轉義符來判斷整個數據長度
……
這讓我們很頭疼,那怎麼 解決了,既然無法知道的東西,就讓應用程序來告訴你唄。和上面一樣,傳入一個協議實現唄:
public interface UnZipDataAction{
byte[] getRealData(byte[] recvData);
ErrorCode getErrorCode();
}
// 返回null,表示未接收完全,繼續接收,返回完整的byte[]就認爲是已經接收完畢,把結果返回給應用,並且斷開連接
這樣,我們就把“連接->發送數據->接收數據->斷開連接->回調結果”整個流程封裝成了通用的功能塊了。
解耦總結來說就是:你能知道的東西就寫死,不知道但是又必須知道的東西,就讓應用程序來告訴你,在java裏面叫接口,在有些語言(OC, swift, C/C++)裏面叫做代碼段。
————————————————
版權聲明:本文爲CSDN博主「烏溪人」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/fangqiangqi/article/details/79826376