6年iOS開發程序員總結組件化—讓你的項目一步到位

純個人學習筆記分享, 不喜勿噴,自行取關!

技術不缺乏締造者,網絡不缺乏鍵盤俠,但缺乏分享技術的源動力!

近幾年組件化大家吵的沸沸揚揚的,它其實也不是什麼黃金聖衣,穿上立馬讓你的小宇宙提升幾個檔次,也不是海皇的三叉戟,入手就能呼風喚雨,它不過就是一種app的架構思路。其實真的很簡單,如果你的項目從發佈之初就是用組件化,那麼在開發的過程當中勢必會少很多麻煩,難點其實是對我們龐大古老的工程進行組件化的改造。

一.下面我們來談談組件化到底是什麼

其實組件化說白了就是將一個單一的工程分解為各個獨立的組件,然後按照某種方式任意組織成為一個擁有完整業務邏輯的工程。

舉個例子大家就明白了,一輛完整的汽車從來都不是由一個工廠將所有的零部件生產完成的,而是輪胎廠生產輪胎,發動機廠生產發動機,玻璃廠生產玻璃等等,然後再組裝成為一輛完整的汽車。我們的各個組件或者說模塊就是汽車的各個零部件,我們的整個工程我們也把它叫做宿主工程就是我們的汽車,我們按照一定的規則把他們拼裝起來就是一個業務邏輯完整的工程。

二.組件化產生的原因

那麼組件化為何應運而生,其實在我們的開發過程中,如果本身項目的規模不大,業務線比較少,人員也比較少,我們使用一般的單一開發模式就好了。但是隨著我們的項目不斷的迭代更新,業務線越來越多,發開人員也組件增多,這個時候就會暴露各種各樣的問題

  • 耦合性嚴重
  • 編譯速度慢
  • 測試不獨立
  • 無法使用自己擅長的設計模式
  • ......
  • 耦合性嚴重
  • 關於耦合性嚴重這點舉個大家深有體會的例子,我們對接手二手甚至N手項目的時候都是深惡痛絕的,因為我們不知道以前的開發人員的思路和架構,這個時候我們往往面臨著三類問題
  • 1.代碼的重構
  • 2.增加新功能
  • 3.改bug
  • 就拿我們改bug來說,我們由於不瞭解人家的思路,我們把面前的bug改掉了,結果我們出了更多得bug,越改越多,頭疼至極,因為我們可能將眼前bug改掉的同時,其他同樣依賴改動地方的代碼卻不適用了,這就非常尷尬了。
  • 同樣地對我們的新功能開發和代碼重構也是如此,我們好不容易將自己的功能模塊搞定的時候,由於對老模塊有依賴,一旦老模塊中存在某些bug,會導致我們整個工程都跑不起來,我們不但測試不了自己新寫的功能模塊,而且我們可能連bug在哪都不是一時半會兒就找到的,再加上解決的時間我們將耗費大量的時間和精力,大大降低了我們的發開效率。
  • 編譯速度慢
  • 隨著工程的業務線越來越多,發開人員不斷增加,我們的項目越來越龐大,往往項目編譯少則一兩分鐘多則幾分鐘,雖然並不影響我們的開發工作,但是我們使用組件化的開發配合二進制化,我們完全可以提高整個項目的編譯時間。
  • 測試不獨立


6年iOS開發程序員總結組件化—讓你的項目一步到位


從這張圖我們能看到我們在發開完畢我們自己的模塊之後,我們需要對自己的模塊進行測試,但是主工程裡面的其他模塊存在一個bug,導致我們的工程編譯不了,那麼我們開發的模塊勢必也是測試不了的,真的很尷尬。

  • 無法使用自己擅長的設計模式
  • 這個我們稍微說一下大家應該能明白,如果你的公司主要是使用MVVM的架構模式進行開發的,而你只會使用MVC進行開發,是不是很尷尬,當然我們可以按照MVC去套用MVVM進行開發,但是我給大家畫一張圖大家就明白了


6年iOS開發程序員總結組件化—讓你的項目一步到位

假設說我們的設計模式按照模塊劃分的話,我們沒法使用MVC去套用我們的MVVM,這樣我們除了去學習MVVM之外別無他法,可關鍵是你真的有足夠的時間在短時間內上手嗎?

當然如果我們按照功能模塊來劃分的話,我們的MVC倒是可以套用我們的MVVM,但是你能保證不出問題嗎?

三.組件化的優勢

那麼我們使用組件化之後到底能達到什麼樣的效果呢?

  • 組件的獨立
  • 我們終於可以獨立編寫我們的模塊,獨立編譯而不用漫長的等待主工程長達數分鐘的編譯,我們再也不用擔心因為各種非自己功能模塊中的bug讓我們寸步難行無法單獨測試了。
  • 資源的重用
  • 我們項目中各種分類,宏定義,基礎配置這些基礎的代碼,以及我們的輪播器,選項卡等等這些功能性的自定義UI組件再也不用重複的拖取或者重寫,我們只需要以pod庫的形式直接導入到工程中就OK啦。
  • 高效的迭代
  • 當我們需要增加或者刪除某些模塊,我們只需要將對應的路徑刪除掉,就可以一次性將整個模塊增加或者移除又不會影響宿主工程的正常運行,十分高效。
  • ※配合二進制,可大大提高項目的編譯速度
  • 我們把業務性、功能性、基礎性的模塊拆分成組件以後,可以採用靜態庫打包,framework庫的形式二進制化組件,這樣將大大提高我們的編譯速度。

四.組件化應該考慮的問題

  • 組件的劃分
  • 我們一般將組件劃分為三類
  • 基礎組件:
  • 包含基本配置(常量,宏)、分類(各種系統類的擴展)、網絡(AFN、SDWebImage封裝)、工具(日期時間處理、文件處理、設備信息等)

功能組件:

包含控件(彈幕、輪播器、選項菜單、圖文菜單等)、功能(斷點續傳、音頻處理等)

業務組件:

業務線一(子業務線一,子業務線二.....)

業務線二(子業務線一,子業務線二.....)

  • 組件層級之間的關係


6年iOS開發程序員總結組件化—讓你的項目一步到位

從這張圖我們可以看出來,我們三大組件類,其實是有層級關係的,我們的業務組件既要使用我們的基礎組件也要使用我們的功能組件,它屬於我們基礎組件和功能組件的上一層,而我們的基礎組件和功能組件屬於同一層級,他們之間是不能互相產生依賴關係的。

如果說我們的功能組件的彈幕需要使用到基礎組件中的有關佈局View的分類,我們這個時候最好的做法並不是將讓我們的功能組件依賴於我們的基礎組件,這樣的話別人要使用我們的彈幕卻要將我們整個基礎組件都下載下來,那麼我們的組件化就失去了原有的意義。我們在這裡推薦的做法是講我們所需要的那塊代碼直接拷貝到我們的功能組件當中去,這樣做的好處在於我們的功能組件不需要依賴我們的基礎組件。

同樣在我們三大組件類的內部,組件之間也不能產生依賴關係,好比我們的彈幕不能依賴於我們的播放器,總不能別人要使用我們的彈幕還得把播放器給下載下來把,這樣也是不合理的,對我們業務組件也是一樣的,我們要增加或者刪除某個業務線,結果導致其他的業務線沒法正常的使用了,這都是不可取的。

但是某些時候我們確實需要使用其他組件裡面的內容,但是他們之間又不能產生依賴關係,這個時候我們就要使用到組件間的通訊,這個在後面會講到組件間如何通訊。

  • 組件的存在形式
  • 組件內部:根據設計模式劃分文件夾結構
  • 組件形式(對外):每個組件都是以pod庫的形式存在
  • 組件測試:單獨的測試工程(這裡我們可以通過創建pod模板庫形式,直接擁有測試工程)
  • 我們是以Cocoapods的形式安裝各個組件的


6年iOS開發程序員總結組件化—讓你的項目一步到位


Enter your image description here:

這張圖我們可以看到,我們的業務組件是可以依賴我們的基礎組件和我們的功能組件的,而我們的業務組件都是以pod庫的形式藉助我們Cocoapod安裝到我們宿主工程中去,我們的宿主工程面向的都是我們的業務組件。

  • 組件間的通訊
  • 上面提到了我們同層次間的組件或者是我們三大組件內部的組件之間是不能有依賴關係的,但是確實有些時候我們一個組件內部發生了一些事件想要告訴其他組件,或者需要調用某些組件的服務,這個時候我們就需要用到組件之間的通訊。
  • 這裡我們來講講其中的一種方式--中間件,我們用一張示意圖來描述一下


6年iOS開發程序員總結組件化—讓你的項目一步到位

在這裡我們看到我們組件都是通過中間件來進行交互的,組件將內部發生的變化告訴給中間件,中間件在通知其他組件。我們組件把各自的服務給中間件,需要對應服務的組件就會去找中間件拿,這樣的話我們組件之間不會產生依賴關係,同時又能進行通訊。

五.分離組件的難點--解耦

一般在組件化的分離各個組件的時候,解耦這個話題我們是迴避不了的,但是其實我們一般會遇到兩種情況

1.組件裡面依賴其他公共功能

2.組件內部需要對接某個服務

組件裡面依賴其他公共功能

對於這種情況,我們一般最快的方式就是直接copy代碼,雖然這個過程比較噁心,但是好處就是不會有額外的依賴,對於一些不重要的工具方法,我們都可以拷貝到內部來使用。

舉個例子大家都明白了,我們使用獲取屏幕尺寸的方法,而這個方法我們一般寫成宏定義放在我們的基礎組件中,我們的業務組件中要用到這個方法沒這個時候我們沒必要把我們基礎組件也整個下載下來,我們直接複製粘貼這短代碼就好了。

我們也可以把組件依賴的代碼先做成一個pod庫,然後依賴這個pod庫就好了,這樣我們的問題就迎刃而解了。

組件內部需要對接某個服務

比如我們控件的內部涉及到加載網絡圖片,我們一般會用到我們的SDWebImage的框架,雖然我們可以在使用遠程私有索引庫的時候添加依賴,那麼我們在下載我們的私有庫裡面組件的時候我們可以將SDWebImage一併集成到我們的宿主工程中。如果開發過程中,公司用得不是SDWebImage不是會很尷尬嗎?

所以我們使用的方式就是使用block或者代理把這部分職責丟出去,那麼我們就可以自用的選擇我們所需要使用的第三方框架或者公司內部寫的框架,不用再糾結了。

需要這份資料可私信“01” 喜歡的話關注加轉發哦


分享到:


相關文章: