隨着項目的不斷迭代,複雜的業務模塊及項目自身的基礎技術組件迅速擴張,以往基於單個模塊的項目每每顯得過於臃腫。代碼目錄結構,包名混亂,代碼模塊職責不清晰,耦合度高,不便維護。基礎公共組件沒有抽取並剝離乾淨,新人上手較難,項目總體編譯慢,等等。因而,近幾年來,基於Gradle構建的模塊化方案獲得迅速應用,甚至在劃分模塊的同時,也能夠將基礎公共組件抽取獨立的項目,並以單獨的Git庫進行管理和維護。html
模塊化的方案,總體上可以很好的將各個模塊按照自身的職責進行獨立劃分,不管是基於業務的,仍是基於技術的角度,得以可以達到「高內聚,低耦合」的效果。java
但現實中,每每還存在一種「居中」的狀況。
1,基於業務或者技術角度劃分的模塊,在職責界定時每每是有粒度的,這種粒度,有可能很大,也能夠很小,若是以過大的粒度劃分模塊,模塊內的代碼耦合和隔離等狀況依然存在問題,若是以太小的粒度分化模塊,使得整個項目最終造成的模塊每每過多,也不太利於總體理解和維護管理。android
2,最終造成的項目模塊,應該是粒度適中的,如基於業務維護的劃分(從產品或用戶視角下的產品功能),基於基於技術視角的基於職責的基礎技術庫的模塊剝離。web
3,最終造成的項目模塊,尤爲是基於業務維護的劃分,最終模塊內依然會存在多個子級粒度的業務,此時,在不宜進一步繼續直接模塊化的基礎上,應該有一套相似模塊化自己思惟的技術方案,以實現模塊內的模塊劃分,或稱之爲代碼隔離。bash
子級粒度的業務,每每不只包含既有的java
代碼,還包括了可能的jar
包或so
文件引入,可能圖片資源,字符串類型資源,以及常見的佈局文件等,此時,若是僅僅是傳統方案下的java
源碼級別的按照目錄形式的劃分,每每是不夠完全的。微信
因而,微信最先對外發布的文章,微信Android架構歷史,其中詳細介紹了其模塊內的代碼隔離方案,pins。
後來,美團外賣中也是參照一樣的思路實現了模塊內的代碼隔離。具體參見:美團外賣Android平臺化架構演進實踐架構
在思惟模式上,pins
其實與項目模塊化自己,具備殊途同歸之妙。而且也是在充分利用了Android Gradle
構建工具基礎上,經過修改指定的源集邏輯,顯示隔離後的代碼及資源文件的從新組合。app
在技術原理上,pins
自身並無太多的技術自己,更多的充分利用了Android Gradle
構建工具,比較巧妙的實現了模塊內的再次隔離。ide
1,將模塊內按照子級業務再次抽取,最終造成與src/main
一樣級別的目錄劃分(與上圖中的微信pins目錄結構有所不一樣),抽取的子級模塊以p_子級模塊名
命名,其中,p_
開頭是爲了後續修改源集邏輯時候的區分標識;模塊化
2,對應剝離具體的子級業務,包含java
代碼,其餘資源文件等;
3,修改對應模塊的Android Gradle
構建時的源集邏輯,主要經過如:java.srcDir
、res.srcDir
等方法將p_子級模塊名
對應添加上去。
對應修改源集邏輯主體部分以下:
android {
sourceSets { main { def src_dir = new File(projectDir, 'src') def dirs = src_dir .listFiles() .toList() .stream() .filter(new Predicate<File>() { @Override boolean test(File file) { return file.getName().startsWith("p_") } }) .map { return it.getName() } .collect(Collectors.toList()) println("pins-module: " + dirs) dirs.each { dir -> java.srcDir("src/$dir/java") res.srcDir("src/$dir/res") } } } } 複製代碼
項目總體,依託模塊化進行總體大的業務和技術模塊劃分,模塊內,依據業務粒度,子級別的參照pins
思路實現模塊內的進一步代碼及資源隔離,基礎的公共技術組件,抽取成單獨的Git
項目庫管理,以造成項目總體上的模塊化實踐方案。