談?wù)劷M件化的歷程

組件化是一個不可避免的階段迄沫,個人認(rèn)為也是一個越早越好的階段。特別在一個公司內(nèi)的產(chǎn)品越來越多的時候外傅,顯得尤為重要。

什么是組件化


組件化的字面意思俩檬,是代碼上可復(fù)用的結(jié)果萎胰,而實(shí)際上組件化遠(yuǎn)不止這個層面。

在沒有組件化的時候棚辽,每個項(xiàng)目都是各做各的事情技竟,包括一個組內(nèi)也是存在重復(fù)造輪子的行為,等到需要抽離獨(dú)立模塊的時候屈藐,又發(fā)現(xiàn)耦合過大榔组,花費(fèi)大量人力來解耦或者重構(gòu),甚至不了了之联逻。

新項(xiàng)目的快速成型

立項(xiàng) ---> 確定需求 ---> 搭建主工程框架 ---> 引入需要的組件 ---> 補(bǔ)充沒有的組件 ---> 成品

在一定的積累下搓扯,一個公司內(nèi)部的新產(chǎn)品開發(fā),都可以快速的搭建起一個擁有公司基礎(chǔ)業(yè)務(wù)組件的框架包归,專心做差異的業(yè)務(wù)開發(fā)锨推,而無須重新花費(fèi)力氣重新開發(fā)這些基礎(chǔ)功能,例如一些性能監(jiān)控公壤,數(shù)據(jù)上報(bào)换可,測試框架等。

研發(fā)思維于流程的質(zhì)變

組件化并不局限于基礎(chǔ)底層的東西厦幅,業(yè)務(wù)邏輯沾鳄,界面封裝都可以成為一個組件,例如通用下發(fā)配置确憨,相機(jī)相冊界面等洞渔,都可以成為大組件化的一個積累過程。

在這樣的環(huán)境下缚态,研發(fā)的開發(fā)流程會變成下面這樣

獲得需求 ---> 前期分析和設(shè)計(jì) ---> Coding ---> 組件化(如果可以) ---> 完成開發(fā)

區(qū)別在于磁椒,在組件化的大環(huán)境下,大家在開發(fā)前期玫芦,會思考這個需求是否可以成為一個通用方案浆熔,而進(jìn)行一些前期的分析和設(shè)計(jì),可以的話,就會從中找到可以組件化的部分医增,成為一個獨(dú)立模塊慎皱。即使不能組件化,也會對于后續(xù)這個模塊的低耦合方面有所貢獻(xiàn)叶骨,引導(dǎo)大家面向接口編程茫多,保持下層穩(wěn)定性。

潛在的激勵

每個研發(fā)都希望自己的代碼得到認(rèn)可忽刽,組件化可以潛在的推動這個事情天揖。從組內(nèi)組件化,到跨項(xiàng)目通用跪帝,到公司內(nèi)公用今膊,最后發(fā)展成對外開源,是一個不斷鼓勵代碼優(yōu)化和維護(hù)的過程伞剑。

探索之路


早期的開發(fā)可能都會經(jīng)歷過這么幾個階段斑唬,現(xiàn)在或許直接就到了最后的形態(tài),再往后就在于是否堅(jiān)持了黎泣。

以下列出了幾種我經(jīng)歷過的工程形態(tài)恕刘,有些或許現(xiàn)在還是這樣,我們可以順著理一下抒倚,這里都是基于iOS的開發(fā)來討論褐着。

一個工程走天下

在早期,或者現(xiàn)在還有些項(xiàng)目衡便,一個app只有一個主程序献起,所有代碼按照文件夾來劃分洋访,實(shí)際上都在一個target上镣陕,很多開發(fā)會覺得很方便啊,這樣有什么不好呢姻政?

  • 容易造成import泛濫
    • import沒有顯示來源呆抑,不利于代碼理解和解耦
    • 沒有一個很好的尋找特定代碼的方向,容易重復(fù)造輪子
      • 文件夾劃分太弱汁展,不利于大家規(guī)劃同類的東西在一起鹊碍,甚至一些通用的基礎(chǔ)方法直接寫在業(yè)務(wù)代碼里
      • 比如系統(tǒng)的Foundation,如果我找一個字符串操作相關(guān)食绿,我一下子就知道該去這里找了
    • 后期要解耦或者抽離的時候侈咕,工作量很大,如果還有交叉循環(huán)依賴器紧,就更痛苦了
  • 代碼沒有得到隔離
    • 太容易觸碰到的東西耀销,很容易誘發(fā)不能用就改實(shí)現(xiàn)的行為
    • 或者完全基于實(shí)現(xiàn)來使用接口,沒有達(dá)到一個面向接口編程的目的
    • owner也沒有動力完善接口铲汪,基于實(shí)現(xiàn)告訴使用者怎么用
  • 跨項(xiàng)目復(fù)雜度高
    • 代碼復(fù)用全靠copy
    • 修改bug容易另外一個項(xiàng)目忘記修改
    • 如果實(shí)現(xiàn)得太業(yè)務(wù)化熊尉,另外一邊也用不起來

當(dāng)然也不能一棍子打死所有案例罐柳,有些app就是簡單,沒必要那么復(fù)雜化狰住,但是怎么也會有一些自定義的基礎(chǔ)類封裝吧张吉,統(tǒng)一管理出來是個好習(xí)慣,說不定那天會感激自己的多此一舉

至于公司級別的app催植,基本上就不會簡單到那個地步了肮蛹,至少我個人是這么覺得的。

多工程模式

多工程模式下查邢,一般有點(diǎn)規(guī)模的一個功能蔗崎,都會獨(dú)立成一個工程,放在主工程下扰藕,成為一個子工程缓苛,主工程依賴這個target即可。

多工程和多文件夾的最大區(qū)別在于

  • 工程可以有不一樣的配置邓深,文件夾只是很弱的視覺劃分
  • 工程有明確的一個獨(dú)立的姿態(tài)
    • 工程一般會有一個Dependency的文件夾未桥,把依賴的文件,庫芥备,子工程放這里冬耿,一目了然
    • 哪天需要復(fù)用,我很快了解這些依賴有什么萌壳,解決這些依賴就可以了亦镶,文件夾的話,你需要看完每個文件的.h.m袱瓮,才能匯總起來一共依賴了些什么
    • 方便整個功能移植到其他app缤骨,或者在demo上測試開發(fā),不影響主項(xiàng)目的流程

這里的好處是沒有異議的尺借,但是怎么很好地解決依賴問題是一個探索的過程

0x1 拖拽文件

從早期我們遇到一個子工程绊起,需要一來到另外一個子工程的文件的時候,第一想到的辦法就是把那些文件的.h拖到這個工程來燎斩,然后發(fā)現(xiàn)這個.h又依賴了另外的.h虱歪,直到把所有頭文件都拖進(jìn)來了,總算完事了栅表。

但是突然有一個文件上的改動笋鄙,這個行為可能要重新做一次,這就很恐怖了怪瓶。

0x2 子工程化依賴

既然我們已經(jīng)用工程化的行為來模塊化了每個業(yè)務(wù)或者說每個功能集萧落,為什么不還局限于對某個文件的依賴呢?

你依賴一個業(yè)務(wù)里面的文件,很大概率你就會用到這個業(yè)務(wù)里的其他文件铐尚,既然這樣拨脉,我們就把文件級別的依賴升華到工程級別的依賴

也就意味著我們不再一個文件一個文件的拖宣增,而是整個子工程拖到自己的工程下面玫膀,那么這個工程就可以訪問整個子工程的公開文件了,何樂而不為呢爹脾?

0x3 統(tǒng)一工程化依賴

但是我們發(fā)現(xiàn)帖旨,依然沒有完全解決這個問題,想象一下灵妨,如果某個工程被其他很多工程都依賴了解阅,而這個工程位置變了,一個基礎(chǔ)模塊工程泌霍,一下子需要放到很多很多工程下货抄,這個操作也是很難受的。

我們想了一下朱转,創(chuàng)建了一個Bridge工程蟹地,所有工程都依賴Bridge工程,同時所有工程都是Bridge工程下的子工程藤为。

乍看之下好像有點(diǎn)死循環(huán)怪与,其實(shí)不然。

  • Bridge工程的編譯并沒有依賴它的子工程的運(yùn)行缅疟,而是依賴子工程下的腳本分别,但是子工程依賴Bridge工程的編譯
  • Bridge工程的編譯會引發(fā)每個子工程腳本,生成自己的頭文件路徑存淫,從而給到使用者
  • 主程序同樣不依賴Bridge工程耘斩,還是按順序依賴其他真是子工程的編譯

這種情況下,為了方便大家纫雁,還創(chuàng)建了一個工程模板煌往,統(tǒng)一標(biāo)準(zhǔn)創(chuàng)建倾哺,且附帶好所有腳本轧邪,唯一需要做的,就是把自己拖進(jìn)Bridge工程的依賴當(dāng)中羞海。

0x4 腳本時代

說到底忌愚,Bridge工程 開始還是需要人為拖動,且不利于新人理解

我們回歸到最原始最本質(zhì)的問題上:可以使用目標(biāo).h文件

清晰了這么一點(diǎn)就好辦了

  • 每個工程只需要搭配一個配置文件却邓,聲稱我這里哪些文件是Public的硕糊,這樣就可以了
  • 然后我們寫一個腳本,遍歷工程文件夾下所有配置文件,在對應(yīng)的目錄生成這些Public Headersoft-link简十,這樣每個子工程都有自己的一個Public Headers的目錄
  • 使用者引用對應(yīng)的路徑即可

(可能很多人覺得這只是一個framework的事情檬某,但是那時候還沒有framework,而且目前一些老項(xiàng)目說不定還在支持iOS7)

腳本能帶來的好處是很大的螟蝙,除了方便了很多以外恢恼,甚至可以做到任何交叉循環(huán)依賴,在每個子工程上可以說用的風(fēng)生水起了胰默。

但是埋下的問題也是很可怕的

  • 首先是這套方案是內(nèi)部使用的场斑,并不能推廣出去,連跨組推廣都有一定的復(fù)雜度牵署,更別說公司外了
  • 然后這套方便的方案漏隐,在設(shè)計(jì)模式層面上,可以說破壞的很厲害了奴迅,會削弱研發(fā)的設(shè)計(jì)思維
  • 使用過程沒有規(guī)范化青责,新人有一定的學(xué)習(xí)和理解成本

Workspace模式

0x5 Pod的到來

Pod的規(guī)范化可以說帶來了一個最終的項(xiàng)目工程形態(tài)(當(dāng)然也有些公司有自己更好的一套方案),主要得益于:

  • 業(yè)內(nèi)的一個通用標(biāo)準(zhǔn)和規(guī)范取具,降低相互之間的一個學(xué)習(xí)成本
  • 更深一層的代碼隔離爽柒,更好的代碼引入方式,更豐富的配置
  • 對私對公的repo機(jī)制者填,插件可自定制化浩村,更少的人為配置依賴操作
  • 不同分支倉庫的組件差異化

對于Pod的模式和使用上,這里就沒必要多說了占哟,可以到Cocoapods的官網(wǎng)了解詳細(xì)的內(nèi)容心墅,也可以Google一些插件定制化的東西來滿足特定的需求。


這里先回答一個疑問榨乎,Pod畢竟也不是很晚期的東西了怎燥,為什么早期或者中期不直接開始引入這個模式呢?

一個客觀原因是蜜暑,在當(dāng)時Pod剛起步铐姚,或者說還沒有到現(xiàn)在這么普及,我們還在觀望和不熟悉的階段肛捍,的確是有點(diǎn)躊躇番甩,通俗點(diǎn)說,對于陌生的東西则奥,就是有點(diǎn)慫迟杂。

另外一個是歷史原因,我們雖然看到前面幾個階段有很多不規(guī)范不成熟的地方缀蹄,但是它們在當(dāng)時的確是一個相對較佳的方案峭跳,我們來分析一下為什么:

  • 這些舊方式都沒有任何難度膘婶,想到一個優(yōu)化點(diǎn)就可以馬上動手,對原來的代碼框架修改很少蛀醉,可以說非常輕量化
  • 0x4模式雖然很大程度上破壞了設(shè)計(jì)模式層面悬襟,但是不得不說在中國互聯(lián)網(wǎng)公司快速開發(fā)迭代的節(jié)奏下,還是獲得很多人的青睞拯刁,畢竟項(xiàng)目的發(fā)版壓力還是有的
  • 歷史代碼的解耦難度大古胆,一下子需要抽離出來,不是一件容易的事情筛璧,另外大家對歷史 相對穩(wěn)定 的代碼逸绎,也是睜一只眼閉一只眼的態(tài)度

阻力是什么


從前面的分析看來,不難發(fā)現(xiàn)夭谤,組件化的阻力從來不是技術(shù)上的棺牧,而是在于流程上的。

從技術(shù)層面上分析朗儒,組件化無非就是

  • 選定組件化的方式
    • Pod的方式對我來說已經(jīng)非常合適了颊乘,不行就加點(diǎn)定制化的東西進(jìn)去
    • 如果牛逼一點(diǎn)的公司可以有自己更優(yōu)的方案,但是畢竟維護(hù)一整套東西也是個成本
  • 代碼解耦抽離
    • 從快速抽離的角度來看醉锄,解耦的做法乏悄,沒有什么是一個中間層解決不了的,如果有恳不,就兩個
    • 復(fù)雜的模塊頂多多費(fèi)點(diǎn)時間檩小,缺乏人力的情況下,甚至可以大合集先包含進(jìn)去烟勋,盡早先收攏再優(yōu)化
  • 后期維護(hù)
    • 只是一個繼續(xù)開發(fā)的過程而已

阻力從來都出現(xiàn)在流程上

組件化的推進(jìn)规求,畢竟不是一個組的事情,也不能局限在一個部門上卵惦。在所有方案都確定好的時候阻肿,你發(fā)現(xiàn)需要跨團(tuán)隊(duì)跨部門跨子公司來溝通的時候,才是真正的阻力沮尿。因?yàn)槊總€部門每個組的情況都不一樣丛塌,他們有著各自的項(xiàng)目壓力和技術(shù)方向,更有著不一樣的想法畜疾。

如何推進(jìn)


推進(jìn)的過程赴邻,我個人覺得是個藝術(shù)活,論外交手腕的重要性(會心一笑)

因?yàn)榧夹g(shù)方案都確定好了之后庸疾,剩下的技術(shù)手段都是苦力活乍楚,真正花時間的可能都是交際手段

  • 推銷方案当编,并得到認(rèn)同届慈,保持步調(diào)一致
  • 確定前期目標(biāo)徒溪,收攏的目標(biāo)項(xiàng)目有哪些,整理出來的組件模塊有哪些金顿,從而確定開刀的主客項(xiàng)目是誰
    • 主客是誰這個很關(guān)鍵臊泌,相當(dāng)于確定公共模塊的標(biāo)準(zhǔn)是誰,用誰的代碼揍拆,以后誰來維護(hù)
  • 資源分配渠概,也可以說是工作模式,最大的阻力環(huán)節(jié)
    • 各個組來各自安排嫂拴,這樣會由于各自的項(xiàng)目壓力和人力播揪,把周期拖得很長
    • 統(tǒng)一出人來幫忙各個組抽離組件,這樣涉及到權(quán)限的問題筒狠,流程上就有點(diǎn)周折
    • 另外還需要有人負(fù)責(zé)打通平臺對接猪狈,使得涉及的平臺支持新的方案
  • 效果檢驗(yàn),這個是最重要的環(huán)節(jié)辩恼,不讓其他人看到效果雇庙,這個事情只會是一次徒勞的苦力活
    • 最容易看到的效果,就是拿新項(xiàng)目來試水灶伊,對比出成品的時間
    • 長期來看的話疆前,就是內(nèi)部開源項(xiàng)目的數(shù)量,組件化的數(shù)量聘萨,甚至對外開源的項(xiàng)目情況
  • 持續(xù)維護(hù)竹椒,需求是源源不斷的,肯定需要有人持續(xù)跟進(jìn)這個開發(fā)流程上的問題
    • 需要持續(xù)優(yōu)化過程中遇到的問題米辐,需要高保證不出錯
    • 提升使用組件化的帶來的副作用而影響的效率

這個過程如果是從上往下推動的話碾牌,顯然比從下往上要容易得多。

最后


組件化顯然是一個不可避免的趨勢儡循,如前面提到的舶吗,我個人認(rèn)為是越早開始越好,對于開發(fā)人員的思維定性來說择膝,一旦長期沒有這個概念誓琼,亂糟糟的代碼是不可避免的,也是會互相傳染而泛濫肴捉。

雖然很多產(chǎn)品現(xiàn)在都是不在乎實(shí)現(xiàn)腹侣,但求無錯不崩潰的態(tài)度,顯示也不是一個可持續(xù)發(fā)展的做法齿穗,一定規(guī)模的公司更是要避免這種短期成品的行為傲隶。

也有一部分公司覺得需要的人力很大,在業(yè)務(wù)重壓之下沒有任何資源來做這件事情窃页。我個人認(rèn)為也是一個比較極端武斷的想法跺株,組件化并不要求一次性到達(dá)一個完美的階段复濒,它和業(yè)務(wù)一樣是一個重復(fù)迭代優(yōu)化的過程,在即使最糟糕的情況下乒省,我也可以把所有明顯的獨(dú)立模塊大集合先抽離出來巧颈,不要求代碼有任何改動,只是單純的抽離袖扛,達(dá)到一個可用的階段即可砸泛,這樣就可以先讓全公司的項(xiàng)目,先用上同一份代碼蛆封,無論是資源的釋放唇礁,還是邏輯上的統(tǒng)一,都是一個非常好的開端惨篱,總之代碼的收攏越早越好垒迂。

一些公司也有自己的SDK組,這些其實(shí)是組件化的前身妒蛇,如果能進(jìn)一步去演進(jìn)和統(tǒng)一操作机断,相信會得到更多的好處。

以上僅代表本人個人想法绣夺,歡迎吐槽和交流

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吏奸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子陶耍,更是在濱河造成了極大的恐慌奋蔚,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烈钞,死亡現(xiàn)場離奇詭異泊碑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)毯欣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門馒过,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酗钞,你說我怎么就攤上這事腹忽。” “怎么了砚作?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵窘奏,是天一觀的道長。 經(jīng)常有香客問我葫录,道長着裹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任米同,我火速辦了婚禮骇扇,結(jié)果婚禮上摔竿,老公的妹妹穿的比我還像新娘。我一直安慰自己匠题,他們只是感情好拯坟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布但金。 她就那樣靜靜地躺著韭山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冷溃。 梳的紋絲不亂的頭發(fā)上钱磅,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機(jī)與錄音似枕,去河邊找鬼盖淡。 笑死,一個胖子當(dāng)著我的面吹牛凿歼,可吹牛的內(nèi)容都是我干的褪迟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼答憔,長吁一口氣:“原來是場噩夢啊……” “哼味赃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虐拓,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤心俗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蓉驹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體城榛,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年态兴,在試婚紗的時候發(fā)現(xiàn)自己被綠了狠持。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡瞻润,死狀恐怖工坊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敢订,我是刑警寧澤王污,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站楚午,受9級特大地震影響昭齐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矾柜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一阱驾、第九天 我趴在偏房一處隱蔽的房頂上張望就谜。 院中可真熱鬧,春花似錦里覆、人聲如沸丧荐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虹统。三九已至,卻和暖如春隧甚,著一層夾襖步出監(jiān)牢的瞬間车荔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工戚扳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留忧便,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓帽借,卻偏偏與公主長得像珠增,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子砍艾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 一位去年到了市區(qū)工作的老師告訴我蒂教,“這里是新天地”。 我被“新天地”三個字所吸引辐董,產(chǎn)生了很多美好的期待悴品。當(dāng)我真...
    沉睡之光閱讀 290評論 0 0
  • “新媒體運(yùn)營”!剛打開標(biāo)題简烘,就好像回到幾個月前一樣苔严,這是我接觸運(yùn)營最早的一個分支,也正是由于這個分支使我開始下決心...
    張大俠丶閱讀 204評論 0 0
  • 有很多正能量的理由孤澎,讓我選擇錢海届氢。 第一,錢海簽合同覆旭,白紙黑字退子,具有法律效應(yīng)。 我們知道現(xiàn)在項(xiàng)目琳瑯滿目型将,挑花眼寂祥,...
    二姐秋梅學(xué)金融閱讀 294評論 0 0
  • Retrofit 配合 RxJava 的使用是越來越廣泛,小到個人項(xiàng)目七兜,大到公司項(xiàng)目丸凭,都能看到它,它的使用也是挺簡...
    程序雜念閱讀 862評論 0 1