pins-模組內的程式碼及資源隔離方案

HappyCorn發表於2019-02-23

隨著專案的不斷迭代,複雜的業務模組及專案自身的基礎技術元件迅速擴張,以往基於單個模組的專案往往顯得過於臃腫。程式碼目錄結構,包名混亂,程式碼模組職責不清晰,耦合度高,不便維護。基礎公共元件沒有抽取並剝離乾淨,新人上手較難,專案整體編譯慢,等等。於是,近幾年來,基於Gradle構建的模組化方案得到迅速應用,甚至在劃分模組的同時,也可以將基礎公共元件抽取獨立的專案,並以單獨的Git庫進行管理和維護。

模組化的方案,整體上能夠很好的將各個模組按照自身的職責進行獨立劃分,無論是基於業務的,還是基於技術的角度,得以能夠達到“高內聚,低耦合”的效果。

但現實中,往往還存在一種“居中”的情況。
1,基於業務或者技術角度劃分的模組,在職責界定時往往是有粒度的,這種粒度,有可能很大,也可以很小,如果以過大的粒度劃分模組,模組內的程式碼耦合和隔離等情況依然存在問題,如果以過小的粒度分化模組,使得整個專案最終形成的模組往往過多,也不太利於整體理解和維護管理。

2,最終形成的專案模組,應該是粒度適中的,如基於業務維護的劃分(從產品或使用者視角下的產品功能),基於基於技術視角的基於職責的基礎技術庫的模組剝離。

3,最終形成的專案模組,尤其是基於業務維護的劃分,最終模組內依然會存在多個子級粒度的業務,此時,在不宜進一步繼續直接模組化的基礎上,應該有一套類似模組化本身思維的技術方案,以實現模組內的模組劃分,或稱之為程式碼隔離。

子級粒度的業務,往往不僅包含既有的java程式碼,還包括了可能的jar包或so檔案引入,可能圖片資源,字串型別資源,以及常見的佈局檔案等,此時,如果僅僅是傳統方案下的java原始碼級別的按照目錄形式的劃分,往往是不夠徹底的。

於是,微信最早對外發布的文章,微信Android架構歷史,其中詳細介紹了其模組內的程式碼隔離方案,pins。
後來,美團外賣中也是參照同樣的思路實現了模組內的程式碼隔離。具體參見:美團外賣Android平臺化架構演進實踐

pins-模組內的程式碼及資源隔離方案

在思維模式上,pins其實與專案模組化本身,具有異曲同工之妙。並且也是在充分利用了Android Gradle構建工具基礎上,通過修改指定的源集邏輯,顯示隔離後的程式碼及資原始檔的重新組合。

在技術原理上,pins自身並沒有太多的技術本身,更多的充分利用了Android Gradle構建工具,比較巧妙的實現了模組內的再次隔離。

1,將模組內按照子級業務再次抽取,最終形成與src/main同樣級別的目錄劃分(與上圖中的微信pins目錄結構有所不同),抽取的子級模組以p_子級模組名命名,其中,p_開頭是為了後續修改源集邏輯時候的區分標識;

2,對應剝離具體的子級業務,包含java程式碼,其他資原始檔等;

3,修改對應模組的Android Gradle構建時的源集邏輯,主要通過如:java.srcDirres.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專案庫管理,以形成專案整體上的模組化實踐方案。

相關文章