現(xiàn)狀
?初到公司熟悉代碼的過(guò)程中,我看到了一個(gè)主控制器里有多達(dá)5000行的代碼,當(dāng)時(shí)我的內(nèi)心是凌亂的。這樣的代碼耦合度如此的高,日后需要如何展開(kāi)迭代和維護(hù)工作了。本著求穩(wěn)的原則,在完全不熟悉公司的業(yè)務(wù)流程的前提下,我和另外一個(gè)開(kāi)發(fā)同事進(jìn)行了幾個(gè)版本的迭代工作,這幾個(gè)版本的迭代工作讓我感受良多。最后得出了一個(gè)結(jié)論:項(xiàng)目代碼框架需要優(yōu)化一下,但是為了不影響現(xiàn)在線上的版本和日常的正常開(kāi)發(fā)工作,我們新開(kāi)了一個(gè)分支進(jìn)行框架的整理和代碼的優(yōu)化工作。
項(xiàng)目分析
?公司主體業(yè)務(wù)是,項(xiàng)目里采用原生和網(wǎng)頁(yè)混合式開(kāi)發(fā)的,網(wǎng)頁(yè)的比例偏重。目前的項(xiàng)目采用的MVC的模式,VC的臃腫問(wèn)題展現(xiàn)的淋漓盡致呀!
VC臃腫的原因有如下
- 分層不明確
-
view層的創(chuàng)建,樣式處理,或者一些其1.1.jpg
?他的處理都是寫在了VC里
?為了同時(shí)兼顧穩(wěn)定性和后序的維護(hù)成本等因素,我們還是決定沿用MVC模式,但是需要分層明確,將代碼完全抽離出來(lái)。
框架結(jié)構(gòu)
- Controller層
- View層
- model層
- 網(wǎng)絡(luò)抽象層
- 數(shù)據(jù)持久層
接下來(lái)我們會(huì)逐步來(lái)講我們的優(yōu)化"路徑"
第一步 工程目錄的整理

?先對(duì)項(xiàng)目需要的模塊進(jìn)行文件管理,這樣就有的大概的"路線"了
- Catergore 分類目錄
- Base 封裝的基礎(chǔ)VC
- Controller 項(xiàng)目中所有模塊的控制器
- Model 項(xiàng)目中所有的model
- View 項(xiàng)目中所有的視圖
- Component 封裝的公共控件
- Global 存放項(xiàng)目中所有的全局的文件
第二步 封裝網(wǎng)絡(luò)請(qǐng)求抽象層

?抽象網(wǎng)絡(luò)請(qǐng)求層為了減少開(kāi)源AFN的代碼侵入性,同時(shí)增加復(fù)用性,其他項(xiàng)目也可以直接拿過(guò)來(lái)使用。
?請(qǐng)求層處理網(wǎng)絡(luò)加載框的狀態(tài),請(qǐng)求的返回狀態(tài)等邏輯。
?封裝完成以后進(jìn)行一個(gè)網(wǎng)絡(luò)請(qǐng)求測(cè)試一下是否有問(wèn)題
第三步 封裝基類的controller

?OCJBaseViewController基類控制器里添加一些公共的邏輯,子類去繼承,但是我們項(xiàng)目里的考慮是不能把所有的東西都放進(jìn)去,目前我們把自定義導(dǎo)航欄和接受的網(wǎng)絡(luò)請(qǐng)求成功的通知放在里面!
?OCJBaseTableViewController 下拉刷新的頁(yè)面都是通過(guò)tableview實(shí)現(xiàn)的,所以封裝一個(gè)基類的tableVC控制下拉刷新的控制器,自定義下拉刷新的動(dòng)畫等
?當(dāng)然,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)。我們也挑選了一個(gè)頁(yè)面來(lái)進(jìn)行替換,檢查時(shí)候有什么問(wèn)題。
第四步 組合使用
?前面的都是單個(gè)的進(jìn)行測(cè)試,現(xiàn)在組合使用。
?本著"柿子撿軟的捏"的原則,又能完整的反應(yīng)問(wèn)題的界面,我們挑選了個(gè)人中心里的積分列表頁(yè)面來(lái)進(jìn)行測(cè)試。
?在積分VC里發(fā)起一個(gè)請(qǐng)求,請(qǐng)求回調(diào)以后在處理業(yè)務(wù)邏輯,那么這樣VC會(huì)有一些數(shù)據(jù)處理的代碼,思考以后覺(jué)得這樣不是很好,為了進(jìn)一步給VC進(jìn)行瘦身,我們VC和網(wǎng)絡(luò)請(qǐng)求層之間在增加了一層,這一層只需要漏出一個(gè)接口就好了,具體的數(shù)據(jù)處理,失敗處理都在在這一層里面進(jìn)行處理的,有圖有真相

我們只需要調(diào)用這個(gè)漏出來(lái)的接口


請(qǐng)求成功以后,去處理響應(yīng)的數(shù)據(jù)

然后發(fā)送一個(gè)通知給對(duì)應(yīng)的控制器

接收到通知以后就可以處理對(duì)應(yīng)的業(yè)務(wù)邏輯了
那么問(wèn)題來(lái)了,可能有的童鞋就在想,通知是廣播形式的,怎么能保證接受者的正確接受了。哈哈,我們可以這樣子解決,請(qǐng)看下圖

在基類的控制器里的init方法里我們給每個(gè)控制器實(shí)例都綁定了一個(gè)隨機(jī)數(shù),我們把這個(gè)隨機(jī)數(shù)當(dāng)做每個(gè)控制器的"指紋",在發(fā)送請(qǐng)求的時(shí)候我們把自己的"指紋"發(fā)送出去,請(qǐng)求完成以后的通知把"指紋"在發(fā)回來(lái),我們對(duì)比一下這個(gè)通知里的"指紋"我們就能得到正確的通知了。即使去韓國(guó)走了一趟,外貌再怎么變化,你的指紋還是沒(méi)有改變的!
第五步 體力活部分
測(cè)試成功沒(méi)有問(wèn)題以后,那現(xiàn)在體力活的部分就來(lái)到了,我們就得一個(gè)模塊一個(gè)模塊的進(jìn)行更改了,這個(gè)部分是最惡心的階段。耗時(shí)間很長(zhǎng)
第六步 換完衣服,該減肥了
在我們的項(xiàng)目里,主控制器里的代碼量"巨大"的原因非常多,我們這只是完成了第一個(gè)階段的工作,第二個(gè)階段的工作正式開(kāi)始。
項(xiàng)目中復(fù)用的視圖控件都封裝起來(lái),只是暴露必要的接口,在vc里我們只會(huì)看見(jiàn)控件的調(diào)用,這也是和前端的控件化思想有一些相似之處吧!所以我們把項(xiàng)目里所有可以封裝的視圖模塊都封裝起來(lái)了

浩浩蕩蕩的框架整理代碼優(yōu)化的階段暫時(shí)先告一個(gè)段落,為了不對(duì)業(yè)務(wù)造成影響,這個(gè)過(guò)程是一個(gè)漫長(zhǎng)的過(guò)程,而且每次測(cè)試都是閑的至關(guān)重要的了!
代碼優(yōu)化是一個(gè)長(zhǎng)期的工作,只要還在維護(hù)的項(xiàng)目,代碼就不可能不需要優(yōu)化,項(xiàng)目不止,優(yōu)化不停!
這是我目前的代碼優(yōu)化工作,以后的優(yōu)化工作在記錄下來(lái)!
Loading....
