iOS開發之組件化

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

一.下面咱們來談談組件化究竟是什麼

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

舉個例子你們就明白了,一輛完整的汽車歷來都不是由一個工廠將全部的零部件生產完成的,而是輪胎廠生產輪胎,發動機廠生產發動機,玻璃廠生產玻璃等等,而後再組裝成爲一輛完整的汽車。咱們的各個組件或者說模塊就是汽車的各個零部件,咱們的整個工程咱們也把它叫作宿主工程就是咱們的汽車,咱們按照必定的規則把他們拼裝起來就是一個業務邏輯完整的工程。架構

二.組件化產生的緣由

那麼組件化爲什麼應運而生,其實在咱們的開發過程當中,若是自己項目的規模不大,業務線比較少,人員也比較少,咱們使用通常的單一開發模式就行了。可是隨着咱們的項目不斷的迭代更新,業務線愈來愈多,發開人員也組件增多,這個時候就會暴露各類各樣的問題app

  • 耦合性嚴重框架

  • 編譯速度慢工具

  • 測試不獨立組件化

  • 沒法使用本身擅長的設計模式 ......佈局

  • 耦合性嚴重 關於耦合性嚴重這點舉個你們深有體會的例子,咱們對接手二手甚至N手項目的時候都是深惡痛絕的,由於咱們不知道之前的開發人員的思路和架構,這個時候咱們每每面臨着三類問題 1.代碼的重構 2.增長新功能 3.改bug 就拿咱們改bug來講,咱們因爲不瞭解人家的思路,咱們把面前的bug改掉了,結果咱們出了更多得bug,越改越多,頭疼至極,由於咱們可能將眼前bug改掉的同時,其餘一樣依賴改動地方的代碼卻不適用了,這就很是尷尬了。 一樣地對咱們的新功能開發和代碼重構也是如此,咱們好不容易將本身的功能模塊搞定的時候,因爲對老模塊有依賴,一旦老模塊中存在某些bug,會致使咱們整個工程都跑不起來,咱們不但測試不了本身新寫的功能模塊,並且咱們可能連bug在哪都不是一時半會兒就找到的,再加上解決的時間咱們將耗費大量的時間和精力,大大下降了咱們的發開效率。學習

  • 編譯速度慢 隨着工程的業務線愈來愈多,發開人員不斷增長,咱們的項目愈來愈龐大,每每項目編譯少則一兩分鐘多則幾分鐘,雖然並不影響咱們的開發工做,可是咱們使用組件化的開發配合二進制化,咱們徹底能夠提升整個項目的編譯時間。測試

  • 測試不獨立

從這張圖咱們能看到咱們在發開完畢咱們本身的模塊以後,咱們須要對本身的模塊進行測試,可是主工程裏面的其餘模塊存在一個bug,致使咱們的工程編譯不了,那麼咱們開發的模塊勢必也是測試不了的,真的很尷尬。

  • 沒法使用本身擅長的設計模式 這個咱們稍微說一下你們應該能明白,若是你的公司主要是使用MVVM的架構模式進行開發的,而你只會使用MVC進行開發,是否是很尷尬,固然咱們能夠按照MVC去套用MVVM進行開發,可是我給你們畫一張圖你們就明白了

假設說咱們的設計模式按照模塊劃分的話,咱們無法使用MVC去套用咱們的MVVM,這樣咱們除了去學習MVVM以外別無他法,可關鍵是你真的有足夠的時間在短期內上手嗎? 固然若是咱們按照功能模塊來劃分的話,咱們的MVC卻是能夠套用咱們的MVVM,可是你能保證不出問題嗎?

三.組件化的優點

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

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

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

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

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

業務組件: 業務線一(子業務線一,子業務線二.....) 業務線二(子業務線一,子業務線二.....)

  • 組件層級之間的關係

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

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

一樣在咱們三大組件類的內部,組件之間也不能產生依賴關係,比如咱們的彈幕不能依賴於咱們的播放器,總不能別人要使用咱們的彈幕還得把播放器給下載下來把,這樣也是不合理的,對咱們業務組件也是同樣的,咱們要增長或者刪除某個業務線,結果致使其餘的業務線無法正常的使用了,這都是不可取的。 可是某些時候咱們確實須要使用其餘組件裏面的內容,可是他們之間又不能產生依賴關係,這個時候咱們就要使用到組件間的通信,這個在後面會講到組件間如何通信。

  • 組件的存在形式 組件內部:根據設計模式劃分文件夾結構 組件形式(對外):每一個組件都是以pod庫的形式存在 組件測試:單獨的測試工程(這裏咱們能夠經過建立pod模板庫形式,直接擁有測試工程)

  • 咱們是以Cocoapods的形式安裝各個組件的

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

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

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

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

通常在組件化的分離各個組件的時候,解耦這個話題咱們是迴避不了的,可是其實咱們通常會遇到兩種狀況 1.組件裏面依賴其餘公共功能 2.組件內部須要對接某個服務

組件裏面依賴其餘公共功能 對於這種狀況,咱們通常最快的方式就是直接copy代碼,雖然這個過程比較噁心,可是好處就是不會有額外的依賴,對於一些不重要的工具方法,咱們均可以拷貝到內部來使用。 舉個例子你們都明白了,咱們使用獲取屏幕尺寸的方法,而這個方法咱們通常寫成宏定義放在咱們的基礎組件中,咱們的業務組件中要用到這個方法沒這個時候咱們不必把咱們基礎組件也整個下載下來,咱們直接複製粘貼這短代碼就行了。 咱們也能夠把組件依賴的代碼先作成一個pod庫,而後依賴這個pod庫就行了,這樣咱們的問題就迎刃而解了。

組件內部須要對接某個服務 好比咱們控件的內部涉及到加載網絡圖片,咱們通常會用到咱們的SDWebImage的框架,雖然咱們能夠在使用遠程私有索引庫的時候添加依賴,那麼咱們在下載咱們的私有庫裏面組件的時候咱們能夠將SDWebImage一併集成到咱們的宿主工程中。若是開發過程當中,公司用得不是SDWebImage不是會很尷尬嗎? 因此咱們使用的方式就是使用block或者代理把這部分職責丟出去,那麼咱們就能夠自用的選擇咱們所須要使用的第三方框架或者公司內部寫的框架,不用再糾結了。

相關文章
相關標籤/搜索