BNA是怎樣做到開發App又(yòu)快又(yòu)穩又(yòu)清晰地
前言
開發者的價值,是通過技(jì )術和産(chǎn)品體(tǐ)現的,對于App開發來說,除了實現業務(wù)之外,最重要的莫過于開發的速度、質(zhì)量和可(kě)維護性,速度決定你能(néng)否支撐公(gōng)司搶占市場,質(zhì)量決定你們能(néng)不能(néng)站穩位置不被迅速踢走,可(kě)維護性決定你們繼續前行時能(néng)否保持輕快的步伐。
速度、質(zhì)量和可(kě)維護性
對速度、質(zhì)量和可(kě)維護性的要求,其實就是又(yòu)快,又(yòu)穩,又(yòu)清晰的要求。
快:快其實是最容易做到,或者說最容易知道能(néng)不能(néng)做到的事情,熟悉的Android開發的朋友都知道,如果能(néng)理(lǐ)清業務(wù)邏輯,不受幹擾地投入開發,開發速度可(kě)以很(hěn)快,一般普通規模的App,一到兩周就能(néng)完成。
穩:穩不像快,可(kě)以簡單地用(yòng)時間進行即時的量化評價,我們要等大量bug出現之後,才知道穩不穩,可(kě)是一般趕工(gōng)速度一快起來,就很(hěn)容易出現大量bug。其實Android常見問題無非是内存、異步、響應等,要排除和解決這些問題很(hěn)容易,難的是怎樣确保不出現這些問題。
清晰:清晰是最難做到的,快可(kě)以通過時間量化,穩可(kě)以通過bug統計量化,但是清晰是很(hěn)難量化的,代碼審查和可(kě)擴展性都是主觀評價,而且相當滞後,很(hěn)多(duō)情況下,往往要等到需要實現擴展,甚至換人接手代碼時,才知道代碼不清晰。
對于開發者來說,怎樣才能(néng)又(yòu)快又(yòu)穩又(yòu)清晰地開發App,這裏梳理(lǐ)了我的幾點心得。
有(yǒu)限參與業務(wù)設計
從職責分(fēn)工(gōng)上,業務(wù)設計是運營部門和産(chǎn)品經理(lǐ)的工(gōng)作(zuò),确實不應由研發負責,但我說的是參與,研發(包括測試)應當盡早參與業務(wù)設計,一方面提前發現問題,另一方面可(kě)以引導和建議技(jì )術路線(xiàn)。
研發參與設計,可(kě)以規避很(hěn)多(duō)問題,例如通信壓力、加載速度、延遲時間、硬件負載等移動開發特有(yǒu)問題,不能(néng)指望運營和産(chǎn)品能(néng)像專業的研發一樣面面俱到,考慮周翔。
另一方面,研發參與設計還可(kě)以引導技(jì )術路線(xiàn),例如采用(yòng)原生App、混合App還是ReactNative形式,采用(yòng)單用(yòng)戶體(tǐ)系還是多(duō)用(yòng)戶體(tǐ)系,采用(yòng)什麽收費形式等。
在實際操作(zuò)中(zhōng),業務(wù)設計諸如收費形式,異常提示,乃至于業務(wù)邏輯上的嚴密性,你都可(kě)能(néng)發現漏洞。
當然,參與設計必然會占用(yòng)研發時間,有(yǒu)人會覺得委屈,感覺這是替産(chǎn)品做了他(tā)們的工(gōng)作(zuò),但其實研發參與設計,省下的還是自己的時間,因為(wèi)無論産(chǎn)品如何設計,最終都需要技(jì )術來研發實現,如果設計上出了問題,你修改代碼的投入,可(kě)比産(chǎn)品改文(wén)檔的那點兒投入大多(duō)了。
當然,公(gōng)司層面也應有(yǒu)清楚的定位,研發對設計的投入,必須是有(yǒu)限的指導性的,如果大量把研發投入到設計工(gōng)作(zuò),就是另一種形式的浪費了。
異常處理(lǐ)
在實際開發過程中(zhōng),除bug其實占了相當一部分(fēn)工(gōng)作(zuò)量,有(yǒu)時候好好的開發計劃,因為(wèi)幾個詭異的bug就得耽誤半天,所謂“碼字5分(fēn)鍾,排錯兩小(xiǎo)時”是也。所以,能(néng)否盡早盡快處理(lǐ)異常,是非常影響開發效率的。
處理(lǐ)異常,我有(yǒu)這麽幾條心得:
提前考慮異常處理(lǐ),在寫正常流程的業務(wù)代碼之前,先考慮異常,“未慮勝,先慮敗”,沿着業務(wù)流程分(fēn)支,先把異常情況都處理(lǐ)掉,例如獲取在線(xiàn)數據顯示一個列表,先考慮網絡異常、服務(wù)器報錯、數據失敗等異常情況,并依次給出相應提示,最後才處理(lǐ)數據正常的情況,你本來就要寫正常業務(wù)代碼和異常處理(lǐ)代碼,你隻需要調換一下工(gōng)作(zuò)的先後順序,其實你投入的開發時間沒有(yǒu)增加,但是你的效率卻大大提升了,因為(wèi)一旦出現異常,我們可(kě)以迅速判斷異常原因,節省大量時間。
這樣做還有(yǒu)一個好處,在你的思維陷入複雜的業務(wù)邏輯之前,先處理(lǐ)相對簡單的異常分(fēn)支,可(kě)以避免你被業務(wù)邏輯搞到大腦缺氧後,再回來處理(lǐ)異常分(fēn)支時一時疏忽手滑,寫錯或者寫漏異常處理(lǐ)。
隔離前後台對接的數據接口,最好不要直接使用(yòng)後台提供的數據,中(zhōng)間加一層映射,一方面,如果後台數據出了問題(數據異常、變更字段等),你在映射數據時就能(néng)發現和定位問題;另一方面,也有(yǒu)利于你采用(yòng)更适合App的數據形式進行數據持久化。
另外,建議做一個接口錄入與檢查工(gōng)具(jù),形式不論,但要能(néng)輕松地維護前後台接口,最好能(néng)自動檢測接口反饋是否正常(服務(wù)器負載過大、字段變更、第三方服務(wù)過期等)。
異常信息的收集、彙總和數據持久化
如果出現異常,最重要的是采集到異常代碼行(如MainActivity第61行)和異常原因(如空指針異常)
結構分(fēn)層
使用(yòng)框架是必須的,Model層,View層必須職責單一,至于使用(yòng)MVP、MVVM還是别的什麽就看個人偏好和項目需要了。
* 個人在結構分(fēn)層上,有(yǒu)這麽幾個經驗:
高内聚的數據層,把與數據讀寫相關的處理(lǐ),網絡讀寫、本地讀寫、緩存數據等,包括模拟數據,都集中(zhōng)到數據層,通過回調或鏈式調用(yòng)等方式抛出數據給業務(wù)層,通過多(duō)版本機制切換模拟數據和真實數據。
松耦合的Activity,界面應該是與業務(wù)相關最低的,主要提供一個顯示載體(tǐ),并觸發生命周期處理(lǐ),Activity應該可(kě)以很(hěn)容易地被替換掉。
獨立且方便測試的業務(wù)層,業務(wù)層應該可(kě)以實現自動化測試,這非常重要,即使你不去實施自動化測試,把代碼寫成可(kě)以自動化測試的,也能(néng)幫你優化代碼,該抽象的抽象,該剝離的剝離。
必要時抽象特殊控件,如果控件需要複用(yòng),就不要讓控件融合進Activity,而是抽象為(wèi)獨立的顯示控件,這樣既能(néng)解耦合,又(yòu)方便複用(yòng)。
不要過度設計
敏捷開發裏有(yǒu)一個實踐原則,就是不要過度設計,開發的價值不在于寫出漂亮的代碼,在于實現産(chǎn)品并支撐其正常運轉,在能(néng)實現産(chǎn)品功能(néng)的前提下,代碼邏輯其實是越簡單越好,簡單往往就意味着高可(kě)靠性+低維護成本,如果将來需要擴展功能(néng),可(kě)以通過修改和重構實現。
當然,簡單并不意味着随意,要把事件做複雜很(hěn)容易,要做簡單卻很(hěn)難。能(néng)做到邏輯清晰、線(xiàn)程安(ān)全、内存安(ān)全,又(yòu)容易修改和擴展的同時,還能(néng)保持代碼簡潔,其實反而更考驗功力的。
其實不僅在開發新(xīn)功能(néng)時要避免過度設計,在維護和擴展舊代碼時,也要注意,能(néng)正常運行的代碼,都是好代碼,我覺得在維護舊代碼時,其實也适用(yòng)開放封閉原則,對不得不改,不改就崩的舊代碼,是開放的,可(kě)以修改的;對能(néng)正常運行的代碼,哪怕你覺得再難看再手癢,那也是封閉的,是不可(kě)以修改的。
回到那句話,開發的價值不在于寫出漂亮的代碼,在于實現産(chǎn)品并支撐其正常運轉。
通用(yòng)庫的建立與維護
我們知道,項目管理(lǐ)有(yǒu)四個要素,時間、成本、範圍、質(zhì)量,這四個要素一般是不能(néng)兼得的,要時間,就得砍一些範圍的項目目标,降成本,就容易犧牲質(zhì)量,等等,不過,建立和維護通用(yòng)庫,卻能(néng)同時對四個要素都有(yǒu)好處。
-
加快開發速度,專注于具(jù)體(tǐ)業務(wù)(時間)
-
降低團隊成員熟悉項目的成本,為(wèi)新(xīn)業務(wù)開發提供基礎,加快開發叠* 代速度,有(yǒu)利于更快地發布版本
-
提高代碼複用(yòng)率,降低開發投入(成本)
-
穩定的公(gōng)共模塊采用(yòng)依賴組件庫方式,提供給各個業務(wù)線(xiàn)協作(zuò)使用(yòng),* 減少重複開發和升級維護工(gōng)作(zuò)量
-
提升開發效率,更容易實現項目目标(範圍)
-
對已實現過的功能(néng)/業務(wù),抽象出通用(yòng)模塊,再有(yǒu)類似的需求,能(néng)夠 迅速實現,更容易實現項目的業務(wù)需求
-
提升産(chǎn)品質(zhì)量,持續改進通用(yòng)功能(néng)(質(zhì)量)
-
頻繁使用(yòng)的功能(néng)/業務(wù)模塊采用(yòng)組件複用(yòng)方式,更有(yǒu)利于暴露缺陷, 一處修改,多(duō)處受益,提高産(chǎn)品質(zhì)量
工(gōng)具(jù)與模闆等
其實說起提高效率,前面的很(hěn)多(duō)經驗因為(wèi)需要在實際開發中(zhōng)慢慢體(tǐ)會,難以迅速上手,反而是工(gōng)具(jù)模闆,真正見效快,一次安(ān)裝(zhuāng),終生受益 :)
就我的經驗而言,對我開發效率幫助最大的,包括代碼模闆、常用(yòng)配置和開發插件,以及著名(míng)的程序員在線(xiàn)交友網站Github。
代碼注釋
一般來說,程序員看自己一個月前寫的代碼,是完全陌生的,我也一樣,基本上過一個月就沒印象了,但是如果要修改/擴展怎麽辦(bàn),這時候,就得看代碼注釋了。就個人經驗而言,有(yǒu)這麽幾個地方,一定要寫注釋:
接口,特别是MVP的Contract接口,這裏面基本定義了你的主要業務(wù)行為(wèi),誰來加載數據,誰來顯示數據,誰觸發的下一步操作(zuò),這些内容寫明白了,以後讀代碼,隻要看接口就知道主要業務(wù)是怎麽回事兒了。
服務(wù)、廣播等,服務(wù)和廣播因為(wèi)沒有(yǒu)界面,容易遊離在業務(wù)邏輯鏈條之外,在業務(wù)邏輯上缺少上下文(wén),就必須有(yǒu)詳盡的注釋,說明其業務(wù)場景。
初始化、注入等,如果自定義了一些擴展的功能(néng)或控件,要求執行某些初始化函數,或者要注入特定功能(néng)的,就必須寫好注釋,提示調用(yòng)者進行必要的操作(zuò)。
TODO,工(gōng)作(zuò)總要排優先級的,有(yǒu)些工(gōng)作(zuò)暫時延後,自己記錄是沒用(yòng)的,團隊開發最終用(yòng)的還是代碼,所以一定要寫TODO,提示開發者,這裏是未完成的狀态,避免不必要的誤會和延誤。
留言