原文出處:http://www.apkbus.com/blog-875309-62984.html
前言
架構設計蜂桶,到底是什么呢?基于這段時間的學習和自己的一些思考也切,我認為架構是基于產品和技術所達成的一種共識扑媚。我不是專業(yè)的架構師雷恃,也不是經驗老道的開發(fā)者旬痹。本文目的有三,一是整理這段時間的架構學習和思考以及總結這一年的開發(fā)經驗教訓讨越,二是希望能夠與各位朋友探討移動端App的架構設計两残,三是希望我們每一個應用開發(fā)者能夠擁有架構的意識。個人的水平有限把跨,文中如果不當之處人弓,還希望批評指正。
一着逐、萌芽
作為一只編程經驗并不怎么豐富的程序猿來講崔赌,我一直覺得架構師是一個比較神秘的職業(yè),架構設計就更加的高大上了滨嘱。經過今年的幾個項目峰鄙,之前曾發(fā)文敘述我的從MVC到MVP項目重構實戰(zhàn)經驗浸间,也曾說過我準備對目前手底下的項目進行重構太雨。但是,前段時間魁蒜,我改變了我的想法囊扳。開發(fā)模式的重構吩翻,僅僅只是換了一個套路,也許在重構的過程中對業(yè)務的邏輯進行了一次梳理锥咸,也是在基于前人的代碼設計上進行了一些優(yōu)化狭瞎。但是,這遠遠還不夠搏予,這不是我理想中的開發(fā)場景熊锭。在項目開發(fā)的過程中,也發(fā)現存在許多的問題雪侥,但是都是一些零散的問題碗殷,我很多時候希望能夠改變現狀,更加優(yōu)雅地編程速缨,然后實際的情況卻是陷入了迭代功能開發(fā)和bug修復的死循環(huán)⌒科蓿現在回過頭來想想,我理想中應該是開發(fā)應該是一種由規(guī)劃和設計指導的開發(fā)旬牲,那么架構設計就顯的尤為重要了仿粹。
二、初識架構
1原茅、閱讀《架構之美》之論架構
僅看完了《架構之美》的第一部分:論架構吭历,對架構有了一個大概的認識。下圖是這部分的知識點概要: 書中很受啟發(fā)的概念:
架構是一種折中擂橘,一種取舍毒涧。架構師要學會的就是平衡,質量與成本之間的平衡贝室;
架構師首先關注的不是系統(tǒng)的功能契讲,而是滿足需求,滿足品質滑频;
架構設計要做的是讓關注點分離捡偏,并且對每個關注點進行設計一定的結構,該結構都有利于解答這一個關注點所定義的問題峡迷;
好的架構應該是可以指導產品银伟、開發(fā)、測試人員都對這一設計感到非常的舒適可靠绘搞,該設計覆蓋了所有該軟件系統(tǒng)相關利益的人員以及其中的關注點彤避;
只設計你知道需要的東西,多余的設計是一種浪費夯辖;
架構幾乎影響了該系統(tǒng)相關的所有的人和事琉预,決定了該軟件系統(tǒng)是否健康。
2蒿褂、分析行業(yè)內各個APP的架構演進
這里僅僅通過Google搜索各個app在架構演進方面的一些文章圆米,從中分析他們?yōu)槭裁匆葸M卒暂?怎么演進?帶來了哪些好處? 簡單的整理如下:
(1)架構為什么需要演進
項目需求擴張娄帖,舊的架構不適應新的需求
開發(fā)團隊人員增加也祠,協(xié)作要求變高
新技術引入
更高的軟件質量要求
(2)他們是怎么演進的
餓了么移動APP的架構演進 2016-01-20
模塊解耦
共有組件
業(yè)務組件
Excalibur映射系統(tǒng),注冊機制
引入Hybrid框架
React-Native & Hot Patch
攜程移動App架構優(yōu)化之旅 2016-04-07
工程結構調整近速、業(yè)務之前解耦诈嘿,產品間相互獨立,頁面跳轉使用事件總線或者URL總線方式
統(tǒng)一基礎功能業(yè)務組件削葱,SDK化
性能數據采集永淌、監(jiān)控
Native的插件化和HotFix
糯米移動組件架構演進之路 2016-05-24
組件化
統(tǒng)一服務入口
Hybrid框架優(yōu)化
蘇寧11.11:蘇寧易購移動端的架構優(yōu)化實踐 2016-11-11
分層解耦,解決縱向解耦
中介型引用結構(protocol和url方式)佩耳,橫向解耦
H5容器優(yōu)化
網絡鏈路優(yōu)化
移動App性能監(jiān)控系統(tǒng)
(3)帶來的好處
進行了模塊化的解耦遂蛀,產品相對獨立,應對需求變化干厚、技術更新更加靈活李滴,團隊協(xié)作更加方便,并減少了許多是無用功蛮瞄,也給團隊留下了一些技術積累所坯;
進行了必要的統(tǒng)一規(guī)范,組織結構更加清晰挂捅,系統(tǒng)更加健康芹助;
引入了新的技術框架,闲先,產品獲得更好的體驗状土;
進行了系統(tǒng)的優(yōu)化工作,軟件的品質更高伺糠,體驗更好蒙谓;
3、Google搜索關鍵字:架構設計
搜索引擎對于我們來說是最棒的學習工具训桶,我通過搜索架構設計等關鍵字累驮,閱讀了一些文章,并仔細研讀Keegan小鋼的博客文章《小鋼的架構思考》系列舵揭。這幾篇文章在發(fā)表之初曾閱讀過谤专,但是當時并不怎么理解,大概是對架構還沒有一個大概的認識午绳。在請教一位前輩的時候置侍,他和說了對架構的一個理解,并再次推薦了這幾篇文章。所以我再次閱讀了好幾遍墅垮。下圖是文中關于架構設計的知識概要。
(1)知識概要
(2)個人小結
架構分為三個階段:規(guī)劃耕漱、設計算色、構建,每個階段架構的設計有不同職能螟够。在規(guī)劃階段灾梦,考慮的是產品的需求、質量的需求妓笙,技術的可行性分析以及預研若河。在設計階段,考慮的如果將一個復雜的系統(tǒng)拆分寞宫,并設計如何進行組織這些拆分的模塊萧福。在構建階段,考慮的就是具體的實施問題辈赋,并且要保證一定的伸縮擴展性鲫忍,因為架構是不斷演進的。文中引用了《軟件架構設計》一書的一個模型圖钥屈,我覺得有必要在此貼出來悟民。最近也在思考軟件模塊化的設計,模塊化的設計也許各有理解篷就,在此先不做討論射亏。如下圖:
這張圖我起初理解不是很透徹,我曾嘗試自己去畫一些圖來表達我的一些想法竭业。但是智润,當我再次回過頭看到這張圖的時候,才恍然大悟未辆。 架構的設計可以從兩個維度來考慮做鹰,一是架構思維,二是架構原則鼎姐。思維是我們的思考方式钾麸,是我們解決問題的方法。原則是我們思考問題的方向炕桨,是我們解決問題的一些標準饭尝。
三、架構的定義
對于架構的定義献宫,業(yè)界都各有看法钥平,也曾微信私信請教過一些行業(yè)內有豐富經驗的前輩℃⑼荆《軟件架構設計》一書則將架構定義總結為組成派和決策派:
組成派:架構=組件+交互:軟件系統(tǒng)的架構將系統(tǒng)描述為計算組件及組件之間的交互涉瘾。
決策派:架構=重要決策集:軟件架構是在一些重要方面所作出的決策的集合知态。
keegan小鋼在《小鋼的架構思考:什么是架構》文中提到:軟件架構是規(guī)劃、設計和構建軟件的過程和結果立叛「好簦《架構之美》一書在1.1.3架構的含義中提出:架構說明了設計和構建一個系統(tǒng)所使用的結構∶厣撸《Software Architecture in Practice,Second Edition》中提出:一個程序或計算機的軟件架構是系統(tǒng)的一種結構或一組結構其做,它包含軟件元素、這些元素的外部可見的屬性赁还,以及元素之間的關系妖泄。
本人并沒有經歷過大型的軟件系統(tǒng),做過的也只是移動端App的開發(fā)艘策,所以個人也只敢從移動端app的架構設計出發(fā)蹈胡,給出我一個狹義的理解。我認為朋蔫,移動端的app架構是一種基于產品和技術的進行統(tǒng)籌管理最終所形成的共識审残。可能大部分的app開發(fā)尤其是小團隊app的開發(fā)大多是由產品驅動的開發(fā)斑举,需求來了搅轿,那就技術實現。需求變了富玷,那就改璧坟。畢竟,應用層的開發(fā)是對業(yè)務負責的赎懦,必須保證正常的發(fā)布雀鹃。所以大多數的情況下,程序猿不得不在產品經理面前妥協(xié)励两,這樣對于開發(fā)人員的工作就會變的很被動黎茎。所以,就出現了程序猿和產品狗的撕逼笑談当悔。這種現象的原因在于項目各個相關利益人員沒有對產品和技術達成共識傅瞻,這正是移動端架構設計所要解決的問題。
四盲憎、產品
產品嗅骄,是我們產品經理們設計的結果,也是開發(fā)人員開發(fā)的最終成果饼疙,是前后兩種人群的共同目標溺森。作為軟件的架構設計者應該充分理解產品的設計理念,除了明白已經設計的功能業(yè)務,還得具有一定的預見屏积,掌握產品的發(fā)展趨勢医窿。下面主要從開發(fā)的角度來談一談產品。
1炊林、產品設計(做什么)
作為一名開發(fā)人員姥卢,我不能很專業(yè)的來談產品的設計,但是這里我還是希望以一個開發(fā)人員的角度來講產品設計铛铁。什么是產品設計隔显,我覺得可以從以下幾個方面來思考却妨。
(1)饵逐、用戶群體(什么人用)
顧名思義,我們設計開發(fā)出來的產品最終是讓人用的彪标。所以首先我們得定位產品的用戶是誰倍权?用戶群體代表了我們產品的市場。所以產品做的好不好捞烟,最終市場說了算薄声,用戶說了算。離開了用戶题画,不理解用戶默辨,不注重用戶的體驗,一切都是無用功苍息。
(2)缩幸、核心理念(要做什么)
你知道你最每天累死累活一行一行敲出來的是什么樣的產品嗎?可能對于我們開發(fā)人員很容易陷入到一個版本一個版本的迭代當中竞思,這些永無止境的工作叫人忘記了思考表谊,忘記了問下產品人員,我們最終是要做的什么盖喷?一年后我們的產品將是個什么樣的狀態(tài)爆办,我們的最終愿景是什么?我們將會怎么一步步去實現我們最終的愿景课梳?可能你會說距辆,這些和我開發(fā)有什么關系。接到需求暮刃,我把他開發(fā)出來實現不就ok了挑格。然而,在我們的小組里不乏有這些怨言沾歪,產品人員不斷的修改漂彤,我TM代碼改過來改過去。我們的leader在這方面很強調我們開發(fā)人員應該擁有自己的主動權,可以反駁產品不合理的設計挫望。但是立润,前提是你至少理解產品的核心理念,我們最終要做什么媳板。
2桑腮、迭代計劃(計劃怎么做)
對于一個產品,用戶的需求是很多的蛉幸,而且隨著時間不斷改變的破讨。需求可以分兩種,一種是人性本能的需求奕纫,還有一種提陶,是我們的產品催生的需求奶躯。這兩種需求都是合理的哎媚,也正是我們需要滿足用戶的租谈。對于各式各樣的需求我們怎么有計劃的去實現呢卧须?在敏捷開發(fā)中召锈,我們將這些需求放到一個“需求池”中摸屠,然后進行計劃安排在不同版本的迭代中帆吻。這個工作展运,不僅是產品人員去決定您访,開發(fā)人員也應該起一定的決策作用铅忿。產品人員需要從產品的角度去考慮,開發(fā)人員需要從技術實現的角度去考慮灵汪,最終的計劃應該是兩者的共同決策檀训。特別注意的是,根據產品的特性识虚,技術人員也應該提出技術方面的需求肢扯。合理的迭代計劃可以保證正常的開發(fā)節(jié)奏,完成迭代目標担锤。
3蔚晨、開發(fā)資源(用什么做)
(1)、開發(fā)團隊配置(人)
在《人件》一書中提到了軟件開發(fā)中人的因素很重要肛循,合理配置開發(fā)團隊是非常重要的铭腕。一個App的開發(fā)團隊至少需要5個角色,即產品多糠、交互累舷、UI、軟件夹孔、測試被盈。不同角色也分不同的層次析孽,比如軟件分初級、中級只怎、高級袜瞬。不同角色、不同層次合理搭配身堡,才能夠獲得更高的工作效率邓尤,保證產品開發(fā)順利進行。
(2)贴谎、數據內容配置(物)
產品最終呈現給用戶的是數據汞扎,數據分兩種。一種是私有的數據擅这,是由開發(fā)商自己生產的數據澈魄。一種是平臺自生的數據,是由用戶生產的蕾哟。如果是自己生產的數據一忱,就得考慮數據來源莲蜘,數據的覆蓋率谭确,數據的準確性,合法性等票渠。如果是用戶生產數據逐哈,就得考慮用戶生產數據的動力、入口以及數據安全性问顷、傳播性等昂秃。
(3)、開發(fā)投入預算(錢)
萬事俱備杜窄,只欠東風肠骆。完成一款app開發(fā),需要一支專業(yè)的開發(fā)團隊塞耕,這里的人力成本也是很高的蚀腿。當然我這里只談開發(fā)的預算,至于運營就不說了扫外。我們得考慮莉钙,開發(fā)周期多長、需要多少人筛谚、后期維護怎么辦磁玉。比如一個APP需要5個人開發(fā),2個月的時間驾讲,開發(fā)兩個版本蚊伞,按照每人1W的工資來計算的話席赂,也需要 10W。這估計是最低級別的算法了时迫。所以氧枣,如果是創(chuàng)業(yè)公司,我們在組建開發(fā)團隊的時候别垮,也得看看預算是多少便监,多少錢能辦多大事,當然如果是那些拿到投資無所謂的老板來時得另算了碳想,不過今年死的太多的公司以前都是大手筆烧董。錢燒完了,也就沒有了胧奔。如果是大公司逊移,可能不帶這么摳門的。不過也應該去考慮龙填,開發(fā)團隊會消耗公司多少資源胳泉,我們能否獲得相應或者更高的產出。
(4)岩遗、第三方資源
目前的開發(fā)而言扇商,很多資源是可以尋找第三方合作的。比如宿礁,服務器案铺、云存儲、支付接口梆靖、登錄接口控汉、內容數據以及開發(fā)過程中的一些開源框架等等。我們需要選擇返吻、商務談判直到集成到自己的APP中姑子。
4、產品質量(做的怎么樣)
(1)测僵、用戶體驗
現在對于我們來說街佑,用戶體驗是一個說爛了的詞。那是因為恨课,用戶體驗真的很重要舆乔,決定了一個產品的成敗。產品開發(fā)完成后剂公,最終到達用戶的手中希俩。產品好不好,用戶說了算纲辽。哪些因素影響到用戶體驗呢颜武?我想大概可以從5個角色各自的職責出發(fā)來看璃搜,產品的設計是否直達用戶痛點?交互是否符合人的喜好鳞上、習慣这吻,UI是否讓用戶覺得舒適?軟件的性能好不好篙议?軟件的缺陷是否多不多唾糯?
(2)、軟件性能
從技術的角度來講鬼贱,我們可以通過軟件的性能來分析一個軟件產品的質量移怯。今年許多的技術文章都在談性能優(yōu)化,軟件的性能主要從軟件的啟動速度这难、流暢度舟误、內存、功耗姻乓、流量嵌溢、apk體積等幾個方面來評判。如果想做好一個應用蹋岩,性能優(yōu)化應該納入到日常的開發(fā)中持續(xù)進行赖草。具體如何優(yōu)化,這里就不再多說了星澳。
(3)疚顷、產品安全
產品的安全性可以從兩個角度來看旱易,產品的生產商和產品的最終用戶禁偎。對于生產商而言,有許多的內容是需要受到法律保護的阀坏,有許多的敏感信息如暖,核心技術、網絡接口等是不可以泄露的忌堂。對于用戶而言盒至,我們肯定在本地或者服務器存儲了大量的用戶信息,比如賬號密碼士修,一些信息一旦泄露將嚴重傷害到用戶的個人利益枷遂。所以,為了保護自己以及用戶利益棋嘲,我們必須要生產一個安全可靠的產品酒唉。那么對于一個應用端的開發(fā)者而言,我們的編譯出的apk最終會到用戶手中沸移。所以痪伦,我們需要通過代碼混淆侄榴、數據加密、權限限制等一些技術手段來保護我們的應用网沾。
(4)癞蚕、質量評測
一個應用做的好不好,我認為可以主要從上述用戶體驗辉哥、軟件性能桦山、產品安全三個維度來進行評判。那么醋旦,我們該如何組織這些評判工作呢度苔?我們有在進行這些工作嗎?就目前而言浑度,我相信大多數的產品寇窑、開發(fā)、測試人員都或多或少的參與到這些工作當中箩张,但是也許沒有將一些數據量化甩骏、沒有系統(tǒng)的組織這些工作。目前大部分的應用都集成了行為采集先慷,產品的下載量饮笛、用戶的活躍度等也都是體現產品用戶體驗的主要參數。開發(fā)團隊內部一直在進行性能優(yōu)化的工作论熙,比如異常修復福青、bug修復、內容泄露脓诡,過度繪制无午,apk瘦身。我們也進行了代碼混淆祝谚、數據加密宪迟、apk簽名加密的工作。但是交惯,你知道你的產品質量如何嗎次泽?相比同類產品來,你哪些做的好席爽,哪些做的不好嗎意荤?所以,我覺得將上述這些零碎的工作有系統(tǒng)的組織起來只锻,將一些影響因素進行量化玖像,讓我們更加清楚的了解我們的產品質量是一件非常有意義的事情。
5炬藤、風險規(guī)避
(1)御铃、人力變動風險
人是善變的碴里,尤其對于IT來說,人員的流動就更加的頻繁了上真,公司內部的調整咬腋,員工跳槽等等。所以睡互,對于一直開發(fā)團隊根竿,必須要考慮到人員變動的風險。如果就珠,某某不在了寇壳,項目是否可以正常運行。開發(fā)團隊之間是否能夠交叉熟悉各自之間的業(yè)務妻怎。
(2)壳炎、上層決策風險
是否經歷過一個項目做到一大半業(yè)務被停掉了的情況?而這個時候逼侦,你做的是個半吊子匿辩。如果出現了這種情況,我們該怎么辦榛丢?假設就在剛才你的老板說你現在的項目不做了铲球,那么如何才能最大程度的挽回損失?如何進行項目的收尾工作?而不至于在項目又突然重啟的時候接收的是一個爛攤子晰赞。
(3)稼病、項目延期風險
我們在項目開發(fā)的時候會進行評審,然后按照迭代計劃開發(fā)掖鱼,但是在開發(fā)過程中一定會有許多問題影響我們的預期然走,比如需求變動、技術難題等等锨用。項目延期在軟件項目的開發(fā)中是普遍存在的問題丰刊,對于某些迭代而言,可能并不對整個項目造成重大影響增拥,但是這個問題是一定需要考慮的。并且寻歧,我們應該嚴格的掌控項目的進度掌栅,平衡這些問題,保證能夠按時交付產品码泛。
(4)猾封、軟件缺陷風險
我們應該隨時能夠提供一個穩(wěn)定的版本,這是我們的leader所要求的噪珊。軟件的缺陷存在是正常的晌缘,我們不停的寫bug,也在不停的修改bug,對于那些隱藏很深的bug也許沒有讓測試測出來齐莲,最后流通到用戶的手中,這個時候我們如何完成緊急修復磷箕?如何快速響應能給到用戶一個穩(wěn)定可靠的版本选酗。這些是我們需要考慮的,任何時候岳枷,都應該有PlanB芒填。
(5)、人為失誤風險
前段時間空繁,公司內由于操作失誤殿衰,上架更新一個apk的時候不小心發(fā)錯了機型,導致使用該機型的用戶升級后程序無法使用盛泡。然后闷祥,由于這個機型缺少維護,找不到代碼傲诵,僅僅只能找到一個apk文件蜀踏,然后只能考慮反編譯升級等等。我想掰吕,類似于這類的人為失誤還有很多果覆,比如代碼提交錯誤,集成路徑出錯等等殖熟。人總有一不小心的時候局待,所以,我們在設計的時候菱属,應該將這些因素考慮進去钳榨,如何在出現失誤的時候主動警告,如何在用戶錯誤已經發(fā)生的時候啟動緊急方案纽门,將不良影響降到最低薛耻。
6、產品交付
(1)赏陵、測試版本
在敏捷迭代開發(fā)中饼齿,我們基本上能夠一周提交兩個測試版本。我們開發(fā)一部分蝙搔、修復一部分缕溉,都可以提交一個可測試的版本,這樣可以最大程度的降低開發(fā)風險吃型,有利于軟件的穩(wěn)定性证鸥。
(2)、灰度機制
如果你產品的用戶量夠大,這個時候發(fā)布新的版本就得慎重考慮枉层,用戶才是你的產品的檢驗員泉褐。目前基本都是使用灰度發(fā)布的策略,先給少量的用戶發(fā)布鸟蜡,看看用戶的反饋膜赃,而后逐步發(fā)布給所有用戶。
(3)矩欠、版本管理
我們在開發(fā)過程中有許多的版本财剖,也有很多分法。如debug和release版本癌淮,有的時候還需要給內容提供測試數據的data版本躺坟,還有的時候上一個版本還沒有正式發(fā)布我們就需要開發(fā)下一個版本的功能。我們如何去管理各個版本的代碼以及如何通過版本名來區(qū)分這些版本乳蓄?我們需要制定一定的管理規(guī)范咪橙,并且這一規(guī)范是否在開發(fā)團隊中達成共識,就顯得非常重要虚倒。
五美侦、技術
前面啰嗦了很多,終于寫到這里了魂奥。對于一個開發(fā)人員來說菠剩,怎么做才是我們的關鍵問題所在。只會Android開發(fā)耻煤,所以以下只討論Android具壮。我主要從以下幾個方面來談一談怎么做這個問題。
1哈蝇、技術選型
(1)棺妓、 開發(fā)平臺
移動端的開發(fā)目前主要是兩大陣營Android、IOS,其他的就不多說了炮赦。
(2)怜跑、 開發(fā)工具
編譯工具:Eclipse&Ant、AndroidStudio&Gradle吠勘,作為Android開發(fā)者性芬,目前毫無疑問應該選擇AndroidStudio&Gradle;
代碼倉庫:Git 、SVN ,工具有海龜看幼、AndroidStudio也集成了VCS批旺;
Maven倉庫:可以使用nexus創(chuàng)建自己的maven私服;
持續(xù)集成:Jinkens诵姜、Buildbot、Travis CI、Strider棚唆、Integrity暇赤;
(3)、 開發(fā)語言
Java宵凌、Kotin鞋囊、Grovvy、SQL等等瞎惫;
(4)溜腐、 開發(fā)模式
MVC、MVP瓜喇、MVVM挺益、clean等,各有優(yōu)缺點乘寒,在此不做詳細說明望众;
(5)、 開源框架
都說了不要重復造輪子伞辛,因為你造的輪子不一定不人家的好用烂翰,對于我們開發(fā)者而言,有一件非常好的事情就是我們有太多的開源免費的第三方庫供我們使用蚤氏,這樣給我們省去了大量的工作甘耿,做到更加高效的開發(fā)。但是竿滨,如何選擇佳恬,是否引入使我們需要考慮的一個問題。下面列出一些常用的第三方庫姐呐,更多請點擊殿怜。
網絡:okhttp、 android-asyn-http曙砂、 volley头谜、 Retrofit
事件總線:otto、 EventBus
依賴注入:Dagger鸠澈、 RoboGuice柱告、 ButterKnife
圖片:Fresco、Glide笑陈、 picasso
數據庫:GreenDao际度、 Ormlite、LitePal
Json解析: Gson涵妥、JackSon乖菱、 FastJson
響應式編程: RxJava、 RxAndroid
異常統(tǒng)計平臺:騰訊Bugly、Crashlytics
性能優(yōu)化: blockcanary窒所、 leakcanary
(6)硝逢、 新興技術
軟件開發(fā)而言寂祥,新技術的發(fā)展相當迅速僧免,然而我們實際落地到項目中卻需要很長的時間聋溜,因為新的技術剛出來一是需要學習成本,二是需要承擔新技術不夠成熟皮官,存在缺陷帶來的一些風險脯倒。當然,我們應該積極的引入好的新的東西捺氢,跟得上時代的步伐才好藻丢。下面列舉的一些也許都算不上新的東西,但是也是近年來大家所追捧的新技術讯沈。
AndroidSupport:DataBinding郁岩、MaterialDesign等;
混合開發(fā):ReactNative缺狠、Hybrid问慎、Weex等;
編程語言:Java8挤茄、Kotlin如叼;
熱修復:AndFix、HotFix穷劈、Tinker等笼恰;
構建:InstantRun、Freeline
2歇终、業(yè)務拆分
我們在進行業(yè)務拆分的時候社证,我認為可以將業(yè)務分成三類:
(1)、常用基礎業(yè)務
基礎業(yè)務主要是我們的app的一些基礎功能评凝,像我們公司有BFC團隊給我們開發(fā)了文件上傳下載追葡、網絡請求、行為采集奕短、賬號系統(tǒng)等SDK宜肉,免除我們一些重復的勞動工作。怎么去定義什么業(yè)務才是基礎業(yè)務呢翎碑?我覺得可以這么去區(qū)分谬返。如果你的業(yè)務在行業(yè)普通的應用app都有需要,那么這些這些就是具有普遍適用性的基礎業(yè)務日杈。我們根據不同的功能進行拆分遣铝。
(2)佑刷、通用技術業(yè)務
通用技術業(yè)務我覺得是和自己app相關并且有技術性很強的業(yè)務,可能是你應用的核心技術部分翰蠢,比如美顏這一類軟件的圖片處理项乒,小猿搜題這類的圖片識別等就是一項通用技術型業(yè)務啰劲。通用技術業(yè)務的特點就是在和你同一類的app都會有需要使用的技術梁沧,我們可以根據不同的技術領域進行拆分。
(3)蝇裤、特定功能業(yè)務
特定功能業(yè)務就是屬于你自己app的特定功能了廷支,一般可以按照功能進行拆分成不同模塊。比如說我目前的一鍵搜(類似于小猿搜題)主要有搜題栓辜、查單詞恋拍、翻譯三大功能。那么就可以分拆為三大塊藕甩。搜題要經過拍照施敢、框題、圖片處理狭莱、網絡請求等步驟僵娃,每個步驟都可以看成一塊小業(yè)務,以此進行拆分腋妙。特定功能業(yè)務大部分僅適用于你自身的APP默怨。
以上的說法僅從自身的經驗出發(fā)來進行描述,在我們實際的開發(fā)中可能會有一些特殊情況骤素,或者有不同的拆分分方法匙睹。總之济竹,業(yè)務的拆分還需要根據實際情況來痕檬。
3、架構設計(關注點分離送浊、抽象)
(1)梦谜、核心概念
關注點分離
世上本沒有架構,關注點一分離就有了架構罕袋,我們將一個軟件系統(tǒng)的開發(fā)從多個維度將我們的工作進行拆分改淑,對于每個領域進行設計,將各個領域有系統(tǒng)的組織起來浴讯,這種組織結構就是架構朵夏。然而如何將一個復雜的系統(tǒng)將關注點進行合理的分離,這個是非常有挑戰(zhàn)的榆纽。
抽象
抽象仰猖,這是在請教一位前輩時最后給我強調的一點捏肢。如果你對app是跟著交互走、一個頁面一個頁面寫的饥侵,那么很顯然鸵赫,你沒有對你的業(yè)務進行抽象,而只是在實現躏升。作為java的設計思想也很強調抽象的概念辩棒。那抽象到底是什么呢?抽象就是你要做什么膨疏!更簡單的理解就是一睁,寫interface而不是class。不知道大家有沒有這樣的經歷佃却,在我們的MVP的開發(fā)當中者吁,我們有個Model,也有一個IModel饲帅,但是我們寫完了Model才知道怎么寫IModel,最后成了粘貼復制的體力勞動复凳。如果你是這么做的,你可以自己思考下灶泵,假如我們先寫是IModel,而不是Model,那就是怎么樣的體驗呢育八?這就是將你的業(yè)務進行抽象。在架構的設計當中丘逸,你只需要知道你要做些什么单鹿?而不需要去過多的關注你具體怎么去實現它,這才是設計深纲。
(2)仲锄、設計思維
面向過程(Procedure Oriented)
眾所周知,在C語言的開發(fā)中湃鹊,我們的邏輯大多是根據任務的流程走儒喊。這是面向過程的典型例子。面向過程關注的是工作的流程币呵、一步一步的完成任務怀愧。
面向對象(Object Oriented)
Java語言作為面向對象開發(fā)的典型代表,這是我們所熟知的余赢。我們將計算機按照人的思維來進行設計芯义,每一個對象都持有自己的屬性,并且持有自己的操作方法妻柒。對象之間有繼承扛拨,組合等關系,通過組織這些關系來完成我們的程序举塔。就像社會的人和物一樣绑警,人與人之間各種復雜的關系組合完成了社會各項活動的運轉求泰。
面向切面 (Aspect-Oriented)
面向切面是為彌補面向對象中的一些缺陷而生的,我們將某些功能封裝到一起计盒,提供對外的接口渴频,方便在任何地方調用。就如SharedPreferences, Json, Xml, File, Device, System, Log, 格式轉換等,這些通常會在until包里邊北启。它就相當于一個橫截面卜朗,我們可以隨時面向這個橫截面完成操作,而自己的邏輯里邊不再需要重復的設計暖庄。
面向服務
面向服務是將系統(tǒng)進行拆分聊替,分成一個個獨立的程序或組件,并對外提供某一項服務培廓。每項服務之間通過某種協(xié)議進行通信,并進行分開部署春叫,如HTTP肩钠,從而達到松耦合的目的。
以上四種思維重點在于看待問題的角度不同暂殖,不同的角度解決問題的方案就不一樣价匠,當然各種角度各有優(yōu)劣。那么對于在android開發(fā)中是否都只是按照OOP原則來設計呢呛每?很顯然不是踩窖。面對不同的需求,不同的場景晨横,我們需要及時調整自己的思維洋腮,靈活運用,尋找最適合的角度手形,拿出最優(yōu)的設計方案啥供,這才是我們所追求的。
(3)库糠、設計原則
高內聚
怎么理解高內聚伙狐?我認為我們在拆分時某一細分領域只完成單一的功能,其內部的事情自己處理瞬欧。從表面來看比如一個model的class贷屎,對外提供了一個接口,那么他有一個輸入艘虎,一個輸出唉侄。單獨看這個接口而言,它是高內聚的顷帖。當然美旧,其內部的組織結構有可能千差萬別渤滞,所以內聚的形式又各有不同。所以我們將他們分類為功能內聚榴嗅、順序內聚妄呕、時間內聚等等。
低耦合
耦合指的是模塊之間存在依賴關系嗽测,關系相互依賴就會相互制衡绪励,這是必然的。所以唠粥,如果耦合度太高的話疏魏,將會導致牽一發(fā)而動全身的后果,這個使我們不想看到的晤愧,也極大的影響的程序版本的迭代以及bug的修復大莫。根據依賴關系的不同,我們分為了非直接耦合官份、數據耦合只厘、內容耦合、開關耦合舅巷、控制耦合羔味、外部耦合等等。我們要完成一個系統(tǒng)的開發(fā)钠右,必須要將各個模塊有效的組織起來赋元,這種組織關系便無法避免存在了耦合,我們要做的是盡量減少這些依賴關系飒房,尤其避免交叉依賴搁凸,將耦合度降低到最低,把我們的程序設計的更加的靈活情屹。
適度設計
我們在設計的時候如果考慮不周坪仇,那么設計不夠,不能滿足現有或者可預知的需求垃你,從發(fā)展的眼光來看椅文,會導致后期的開發(fā)中出現很多的問題。如果想的太多惜颇,很容易進行過度的設計皆刺,從而將一個簡單的系統(tǒng)設計的很復雜,那么就給當前的開發(fā)將增加了許多無意義的工作凌摄,降低了開發(fā)效率羡蛾。那么怎樣的設計才是合理的設計呢?我認為能夠同時滿足現有的需求和可預知的需求锨亏,并且面對架構的調整時能夠很方便的進行擴展痴怨。這樣的設計忙干,是非常好的設計。如何才能達到這樣的效果呢浪藻?我個人覺得在對系統(tǒng)進行設計時捐迫,關注點分離的顆粒度需要把握好,系統(tǒng)不過就是將不同單一小模塊進行組織而已爱葵,那么這些細小的模塊就是架構設計的基礎施戴,這就好比建房的那些磚頭。這些磚頭是什么呢?他么可以是是一個對外提供接口的公共方法萌丈,也可以是私有的內部方法赞哗,也可以是某某持用的成員變量。當然往大里看辆雾,他可以是某一個功能模塊肪笋。在上述行業(yè)內各個app的架構演進中,都很強調進行模塊化的改造乾颁。所以涂乌,分離好你的系統(tǒng),才能夠靈活的組織起來英岭,以不變應萬變。
(4)湿右、設計方案
指導模型
下圖在文中已經提到诅妹,這里再次引入,因為這張圖對我的啟發(fā)真的很大毅人,也表達出了我心之所想吭狡。面對一個復雜的系統(tǒng),我們怎么樣去分離丈莺,怎么樣去組織划煮,我認為這張圖已經傳達出了其中的精髓,所以我認為這是架構設計的指導模型缔俄,無論你是什么MVC弛秋、MVP、MVVM之類的俐载,都可以從中去理解蟹略。
模型分解
根據實踐開發(fā)中個人的理解,我將此圖再次進行了簡化如下:
橫向分塊
根據上圖的簡化模型遏佣,我們可以這么理解挖炬,在橫向我們根據業(yè)務功能進行模塊劃分。比如主題商店状婶,我們可以分為壁紙意敛、鈴聲等等模塊馅巷,每個模塊間解耦。同時草姻,在每一層的業(yè)務間再次進行分塊钓猬,比如壁紙在數據層就有圖片的請求、加載碴倾、緩存逗噩、裁剪處理等等。
縱向分層
接下來我們在對每個模塊的業(yè)務根據職責分為展現層跌榔、業(yè)務層异雁、數據層。數據層主要負責數據的獲取僧须、封裝等工作纲刀,業(yè)務層主要更加上層的需要調配各數據層最終將數據返回給展現層,展現層的工作就是將數據展現在UI界面上担平,并且響應人的各種指令切換UI示绊,操作新的數據。
接口通信
在橫向來看暂论,我們將業(yè)務進行了分塊面褐,保證塊與塊之間相互之間沒有任何依賴,保證了絕對的解耦取胎。從縱向來看展哭,每個層級之間的依賴很明顯是無法避免的,所以我們可以保證上層僅依賴下層的接口闻蛀,從而達到降低其耦合度的目的匪傍。
如上圖所示,通過上述橫向分塊觉痛、縱向分層役衡、接口通信這三大步驟之后,我們可以將一個系統(tǒng)進行了很好的分解薪棒,并得到一個理想模型手蝎。當然,這是一個理想的模型盗尸。在我們的實際開發(fā)中可能無法避免一些交叉等特殊情況柑船,我們還需要從實際情況出發(fā)。但是有一點泼各,我們可以保證接口的分離鞍时,已達到更低的耦合度的目的。
統(tǒng)一管理
統(tǒng)一管理,是對于我們的設計中有一些東西是需要統(tǒng)一管理起來的逆巍。通過上述原則及塘,我們將一個復雜的系統(tǒng)進行了拆解,已達到架構設計中將關注點分離的目的锐极。然而在實際的開發(fā)中笙僚,我們除了要進行業(yè)務的分拆,也需要對某些業(yè)務進行統(tǒng)一的管理灵再。比如說一些模式的開關管理肋层,比如說我們在進行網絡請求時需要在測試環(huán)境和正式環(huán)境之間的切換,我們可以將這些模式切換的開關放到一個地方翎迁,方便我們進行管理栋猖,而不要去到各個地方去修改。再比如說我們的請求url地址汪榔,是否可以寫到一起進行統(tǒng)一的管理蒲拉。還有在某些應用中會通過一個中間人來進行統(tǒng)一管理數據的流通、頁面的跳轉痴腌,這也是一個可以嘗試的方案雌团,詳細請看蘇寧易購移動端的架構優(yōu)化實踐文中提到的模塊管理器、Url跳轉管理器士聪。統(tǒng)一管理的意思就是將分拆的某一類小的模塊某一些特性放到某一處進行統(tǒng)一的管理锦援。但是這樣會存在一個問題,比如前面舉例說到的統(tǒng)一開關管理剥悟,這造成了開關耦合雨涛,如何去避免呢?我覺得可以將開關默認寫到自己的模塊里邊懦胞,并公開出修改的接口,方便上層進行統(tǒng)一的修改凉泄,以達到統(tǒng)一管理的目的躏尉。這樣的話,即使這個模塊拆離出來后众,也不會受到影響胀糜。但是,這樣的話蒂誉,其安全性受到了一定的影響教藻。架構設計總是這樣,你總需要選擇一個折中適合自己的方案右锨。
我們通過上述橫向分塊括堤、縱向分層的方法將一個系統(tǒng)切成不同的小塊,這些小塊負責某一單一的職責,然后通過接口將塊與塊之間進行了間接性的連接悄窃,依賴的是接口而不是實例讥电,以弱化這種模塊間通信造成的耦合。當然轧抗,上述模型僅僅只是一個理想狀態(tài)的模型恩敌,如果是一個非常復雜的系統(tǒng),那么層級之間也能拆分出更多的層級横媚。比如纠炮,在數據層,我們在MVP模式的開發(fā)下使用Model來完成灯蝴,當Model層的業(yè)務變得非常復雜時恢口,有部分人會考慮拆分出Data層放在最底層,最為最基礎的數據操作等绽乔。最后弧蝇,為了方便我們對模塊進行組合并進行管理,我們可以考慮在小模塊中開放出接口折砸,供上層進行統(tǒng)一的控制管理看疗。最后,我想說的時睦授,我們在進行業(yè)務分離拆解時可以考慮按照上述的方案來做两芳,最終還得根據實際情況來進行設計。
4去枷、開發(fā)實現
當完成我們的設計工作后怖辆,我們進入了開發(fā)編碼階段,在這個階段主要表達我們的設計删顶,并最終取得實實在在的成果竖螃。當進入這個階段之前,我們的設計不能僅僅是一份文檔逗余,而應該是開發(fā)人員和架構設計者達成的某種共識特咆。再好的設計,也需要獲得良好的表達和實現录粱。下面主要談一談在實現過程中需要考慮的問題腻格。
(1)、項目分包
項目的分包結構體現一個軟件的架構啥繁,我們在進行分包的時候總有一種困惑菜职。因為我們存在多種分法,比如我們可以分為根據類的功能分為activity旗闽、fragment酬核、adapter蜜另、util等,有的時候愁茁,我們又根據功能模塊分蚕钦,比如一鍵搜中有查單詞模塊、有搜題模塊鹅很,同時又存在網絡請求嘶居,軟件升級等小的外圍通用功能模塊。存在的問題就是模塊之間又存在一些可以復用的東西促煮,那么我們進行拆分明顯出現了代碼的冗余邮屁。如果按照兩種方案同時分,那就肯定存在了架構的混亂菠齿。我們該如何達到這兩種的平衡佑吝?我認為,這個也需要更加項目的大小而來绳匀,如果是非常小的項目芋忿,也不存業(yè)務擴展的可能,我們就可以采用上述的第一種方案疾棵,簡單的分類就好戈钢。但是,對于較大的項目是尔,我建議使用第二種方案殉了。下面,我簡單列一個模型僅供參考:
+main
+com.jfg
+common //常用基礎業(yè)務
+util
+wedget
+base
+function //通用技術業(yè)務
+camera
+sensor
+moudule //特定功能業(yè)務
+mouduleA
+model
+presenter
+view
+mouduleB
+model
+presenter
+view
+mouduleC
+demo //主程序
+app
+activity
如上所示拟枚,我們根據開始的項目業(yè)務拆分分包如上起趾,將常用的基礎業(yè)務放到common包里邊桃纯,這個包在大多數情況是不變的壁却,并且為app提供基礎性的服務寺酪,不過我們盡量不要放到這個common包里邊,如果這個common包變得足夠大的時候脚乡,就一定要思考是不是該拆分了鞍恢。因為common給人的感覺就是什么都是,那就讓我們無法快速認知這個包所擔當的職責每窖。我們可以這樣理解,common包是面向切面而設計的一些業(yè)務弦悉,但也不是絕對的窒典。接下來我們先聊module這個包,實際這里是將業(yè)務進行了模塊化的分拆稽莉,如上我們拆分出了moudleA和moudleB瀑志,這兩者之間要求沒有任何的聯系。但是,我們會存在一個問題劈猪,那就是moudleA和moudleB某些業(yè)務是一樣的昧甘,我們拆開顯得重復了許多體力活。這應該是大多數開發(fā)者面對的困擾战得,這種該怎么去平衡呢充边?我是這么考慮的。如果常侦,moudle和moudleB存在重疊的業(yè)務浇冰,我們將這些業(yè)務提取到function包或者common包中,這樣降低了業(yè)務的層級聋亡。我們允許moudle包的各模塊業(yè)務依賴于function和common為我們提供的基礎服務肘习。為了更好的區(qū)分模塊A和模塊B雖然重疊但在邏輯上是各自屬于各自的,我們有兩種方法來做坡倔。第一種是將兩種業(yè)務進行一定的抽象漂佩,實現的過程還是放到各個moudle業(yè)務中。第二種方案定義兩個接口類罪塔,各自定義各自的接口投蝉。在具體的實現類中實現了這兩個接口類的方法,內部在進行相同的邏輯操作垢袱。這樣墓拜,對外看來,邏輯上moudleA和moduleB是分離的请契】劝瘢總之,如何分包還得權衡利弊爽锥,盡量以一種思維來進行劃分涌韩,以避免設計混亂。
(2)氯夷、抽象接口
如果說在架構設計中抽象很重要臣樱,你可能有些迷糊,但是如果要你先寫interface或者abstract class 而不是class時腮考,你就可能感覺得到抽象的意義雇毫。我們將一個系統(tǒng)分解成幾個大的模塊,一個模塊查分成不同的層級踩蔚,每個層級再次拆分成不同的細節(jié)業(yè)務棚放。最后,我們很清晰的知道我們要完成某一項功能需要做哪些事馅闽?對的飘蚯,做哪些事就就是一個個接口馍迄,我們在編碼時先寫接口再寫實現有利于幫助我們對業(yè)務進行拆分和抽象。我們都知道做一件事情一般情況都需要提供一些條件局骤,做完了會有返回結果攀圈。這些都可以在接口的設計中完成。我們需要注意是一個接口只做一件事情峦甩,如果有兩件事非常相似也要盡量拆分而不是合并赘来。在接口命名方面做到見名知意,怎么去評判穴店,就是如果你的接口沒有注釋也同樣能讓人知道你的接口是做什么的就好撕捍。
(3)、數據存儲
數據存儲常用的有SQLite泣洞、SharedPreference忧风、文件等,緩存是否也可以算是一種球凰。這里想強調的就是要注意數據存儲的規(guī)范性以及安全性,如果是數據庫還有必要考慮其擴展性狮腿,如果不滿足需求將會需要進行升級。
(4)呕诉、性能管理
這里源自于對性能優(yōu)化的一點體會缘厢,對于服務端的開發(fā)我們很珍惜服務器資源,應該是看的見的需要銀子買的甩挫。然而贴硫,對于客戶端的開發(fā)我們常常忽略了這一點。雖然手機設備現在擁有大內存伊者,但是如何寫出一個優(yōu)秀的程序英遭,性能也是一個非常重要的指標。性能優(yōu)化處理亦渗,那是我們在更正錯誤挖诸,那么之后應該是少犯錯誤。性能體驗不夠好法精,無非就是對機器設備的內存多律、CPU、GPU資源無節(jié)制的使用搂蜓,造成資源的浪費狼荞,當機器設備無法承受時就會應用就會出現卡段、死機帮碰、異常等不良反應粘秆,嚴重影響了應用的體驗。我們要做的就是要有很強的性能管理意識收毫,對于內存攻走、CPU、GPU等資源按需借用此再,并做到有借有還昔搂,即用完后記得釋放資源。
(5)输拇、特殊處理
我們在開發(fā)的過程中摘符,總有那么多問題并不是按照正常思路出牌的,這些得歸功于我們強大的測試團隊策吠。不同的手法逛裤,就能得到不同的結果,然后就給了我們一堆的bug猴抹。所以带族,我們在軟件的開發(fā)中需要特別注意一些特殊情況的處理,這些最終往往還是邏輯上的死角蟀给。以下簡單總結了一些:
功能沖突
功能沖突可以分為兩種蝙砌,一個是應用內部的功能沖突,二是應用之間的功能沖突跋理。應用內沖突比如A功能和B功能都使用了某資源文件择克,如果在同時使用就會出現問題,我們通常加同步鎖來防止這種沖突前普。應用外的沖突有很多肚邢,比如多媒體、鬧鐘拭卿、日歷骡湖、鈴聲、電話等都肯能引起這些沖突记劈,比如你正在播放一段視頻勺鸦,這個時候來了一個電話,那我該優(yōu)先哪一個呢目木?還有當鬧鐘響起的時候换途,彈出一個界面是豎屏的,那么他就會強制將當前的界面變?yōu)樨Q屏刽射,而如果你這個時候如果是橫屏的話該怎么辦呢军拟?類似于這類還有很多,以后再細細總結誓禁。
極限操作
我們的測試人員喜歡對著某一個按鈕狂點懈息、或者在機器上安裝無數的應用使內存爆滿,或者在磁盤里邊塞滿各種文件摹恰。這些場景雖然并不是理性的用戶所出現的辫继,但實際也是程序的缺陷怒见。所以,我們要注意對這些問題進行處理姑宽。
網絡問題
不可用的網絡遣耍,信號很弱的網絡,網路在wifi和流量之間切換炮车,2G網絡和4G網絡舵变,網絡請求超時等都需要我們針對實際情況進行處理,比如切回到流量的時候進行下載是否有提醒用戶瘦穆。這些處理也算是各個應用的標配了纪隙,就不再多說了。
為null處理
這應該是最常見的問題了扛或,我們平時改bug或者從后臺異常抓取的大多數都是空指針異常绵咱。首先,我們得搞清楚為null的原因是什么告喊?然后我們需要進行為null的判斷麸拄,并警告。
(6)黔姜、Log打印
這里把Log打印單獨拿出來是應為我覺得很需要重視拢切。Log是用來干嘛的?很顯然是用來幫助我們查找問題的秆吵,然后我們大多數的情況下是問題來了再去加打印淮椰,并且TAG五花八門的,是有錯誤的地方用Log.d,而只是查看信息卻是用的Log.e,我們查問題的時候要去閱讀很多的代碼邏輯纳寂,最后再定位到位置主穗。我們在修復bug的時候花了大量的時候再閱讀代碼,這個太影響工作效率了毙芜。如果我們在編碼之初就對Log有了很好的規(guī)范設計忽媒,有異常的地方就用Log.e,可能出現問題的地方就用Log.w等等腋粥,關鍵點的信息用Log.i,臨時調試的用Log.d這樣區(qū)分不是很好嗎晦雨?我們在控制臺一樣就能夠分辨自己需要的信息。我們應該充分應用這個工具隘冲,幫助我們快速定位問題闹瞧。
(7)、軟件重構
重構是因為業(yè)務的需要展辞,也是因為對代碼更高的質量要求奥邮,重構無處不在。我們不要為了重構而重構,也不要一直停滯不前洽腺,該重構時不重構脚粟,欠下太多的技術債務。重構有小到一個方法的重構蘸朋,也有大到整個系統(tǒng)架構的重構珊楼。重構是軟件迭代升級的一個必要過程,也是我們能夠滿足當前需要度液,并且能夠適應未來的發(fā)展,獲得良好的擴展性的必要手段画舌。重構并不難堕担,也不是什么大事,重點在于重構背后的目的曲聂、思想霹购、設計是否清晰。
(8)朋腋、兼容適配
兼容適配的問題是我們開發(fā)一個頭疼的問題齐疙,Android設備無法八門的屏幕尺寸、層次不齊的Android系統(tǒng)版本旭咽。除了進行針對性的處理贞奋,還得提醒產品設計人員在設計之初就得考慮兼容性問題。
5穷绵、軟件測試
軟件測試是我們開發(fā)中非常重要的一到工序轿塔,除了能夠客觀的感應我們所開發(fā)的軟件質量水平,最終目的還是在于幫助開發(fā)人員修復軟件缺陷仲墨,提高軟件的質量勾缭。除了開發(fā)人員提交測試之前的自測,我們需要專業(yè)的測試人員來進行測試目养。人工測試的效率相對較低俩由,所以我們應該考慮通過技術手段完成自動化的測試,如單元測試等癌蚁。這樣有利于軟件的穩(wěn)定幻梯,也同樣的有助于開發(fā)人員提高代碼質量。
6匈勋、開發(fā)規(guī)范
(1)礼旅、設計一致
什么樣的設計才是有規(guī)范的設計呢?我個人認為一個項目保持一致的設計思想就是有規(guī)范的設計洽洁。我們可以這樣去理解痘系,在某一類的情況下,我們按照某一類似的方案來解決這一類問題饿自。面對復雜的系統(tǒng)汰翠,我們一種設計思想也許無法滿足架構的需求龄坪,但是我們只需要明白,這種事情這么干复唤,那種事情那么干健田,相互之間靈活的組合卻也不存在交叉,給人設計思路清晰的感覺佛纫。
(2)妓局、編碼清晰
什么樣的代碼才是高質量的代碼?我覺得結構簡單呈宇,邏輯清晰好爬,一看就懂的代碼就是一份高質量的代碼。所以甥啄,我們可以拋開那些編碼規(guī)范存炮、命名規(guī)范等等,重新去審視自己的代碼蜈漓,看看讀起來是不是很舒服穆桂。如果來了一個新同事,對你對項目一無所知融虽,是否能夠很快速的理解你的思維享完?最后幾點有必要提出,一是慎用設計模式衣形,二是盡量少寫文檔注釋驼侠,三是遵循Java的面向對象六大設計原則。我想這三點就是編碼的原則谆吴,遵守這些原則倒源,形成一種習慣,自然而然就是一種規(guī)范句狼。
(3)笋熬、文檔有效
什么樣的文檔才是有效的文檔,我認為能說明核心問題的文檔就是有效的文檔腻菇。作為軟件開發(fā)人員胳螟,我們沒有耐心去閱讀一份復雜啰嗦的文檔。文檔只需要給我們呈現代碼無法說明的問題筹吐,幫助我們快速理解項目結構糖耸,備忘重點問題,追溯歷史記錄丘薛。文檔的形式又很多嘉竟,比如我們git的提交記錄、tag,項目結構圖、核心功能流程圖等舍扰【腧剑總之,文檔是給人看的边苹,以盡量少的文檔來說明核心問題就好陵且。
7、日常工作
作為一名合格的軟件開發(fā)人員个束,我們有許多的日常工作慕购,如Bug修復、異常處理茬底、Monkey脓钾、性能優(yōu)化、代碼質量改善等待桩警。這些事情并一定要求你每天都要做,但是每天都得關注昌妹,做到心中有數捶枢。如此,才能夠培養(yǎng)一個很好的編程習慣飞崖,寫出優(yōu)秀的代碼烂叔,優(yōu)秀的程序。
六固歪、開發(fā)
1蒜鸡、開發(fā)驅動
一個項目的正常運轉一定是由某一方主導項目的進行,不斷的提出產品需求牢裳,并組織項目成員分工合作逢防,完成產品的開發(fā)交付,以下是兩種驅動開發(fā)模型蒲讯。
TDD:測試驅動開發(fā)(Test-Driven Development)
測試驅動開發(fā)指的是由測試主導開發(fā)的工作忘朝,從產品的使用出發(fā),對產品的功能提出測試要求判帮,組織項目中各個角色完成開發(fā)任務局嘁。
BDD:行為驅動開發(fā)(Behavior Driven Development)
敏捷開發(fā)便是行為驅動的開發(fā),更加強調產品的設計晦墙,鼓勵項目中各個角色提出自己對項目開發(fā)的觀點悦昵,已獲得更優(yōu)秀的產品功能,完成產品的開發(fā)晌畅。
2但指、敏捷開發(fā)
下圖引自網絡上的一張關于敏捷開發(fā)的圖片,目前我們團隊基本也是根據這個模型進行敏捷開發(fā)的。我覺得在敏捷開發(fā)中更加強調的各個角色之間的隨時溝通和快速響應枚赡,我們并不對整個系統(tǒng)進行一份完整而詳細的設計氓癌,而是進行階段的設計開發(fā)工作,并謀求不斷的迭代更新贫橙。在敏捷開發(fā)的過程中贪婉,普遍存在的問題就是溝通不及時、產品變動大卢肃,所以如何動態(tài)的進行統(tǒng)籌管理變的非常重要疲迂。我們通過需求評審、交互評審莫湘、視覺評審尤蒿、Bug評審等由各個有關角色的人員參加評審會議,共同完成決策幅垮,以保證軟件開發(fā)的順利進行腰池。不得不說,這個過程中還是存在許多的問題忙芒,溝通的問題示弓,產品變動的問題,產品功能細節(jié)開發(fā)過程的中流程性的問題等等呵萨,在此不詳細說了奏属,后期有時間再進行總結。
3潮峦、達成共識
敏捷開發(fā)中有一個特點就是囱皿,產品開發(fā)決策是由項目各個角色成員共同完成的,各個角色領域的問題又是由該角色自身最終拍板忱嘹。那么隨之而來的就出現了一個問題嘱腥,各個角色所決定的問題又被其他的角色所制衡。比如說拘悦,產品經理設計的功能在開發(fā)人員而言存在技術難題爹橱,交互的設計存在邏輯上的漏洞。我想窄做,這些問題是一個產品不能按照預期時間完成的真實原因愧驱。那么,哪一個角色來統(tǒng)籌管理這些問題呢椭盏?通常组砚,我們有架構師、項目經理掏颊、老板等等角色來對項目進行把控和管理糟红。
軟件架構的設計來源于產品的需求艾帐,并決定了產品的最終形態(tài)。然而處于敏捷開發(fā)中的我們而言盆偿,產品的需求變化很快柒爸,同時要求我們開發(fā)人員能夠快速響應這種變化。那么事扭,如何保持軟件的整體架構和產品的設計同步更新就顯的非常重要捎稚。
對于開發(fā)者而言,我們首先要對項目有一個整體的認知求橄,隨時掌握產品的動態(tài)今野。這些包括產品的設計、迭代計劃罐农、開發(fā)資源条霜、質量要求、交付要求涵亏、風險規(guī)避方案等宰睡。然后根據產品的需求變化,動態(tài)調整自己的軟件架構气筋,這些工作包括夹厌,技術選型、架構設計裆悄、代碼重構、文檔更新等臂聋,以適應新的需求光稼,并把這種架構共享給相關人員以達成共識。這種共識孩等,是需要對產品和技術進行統(tǒng)籌規(guī)劃才能夠完成的艾君。也只有項目各個相關利益人員能夠達成這種共識,我們的溝通才會更有效肄方,才能做出各方人員都滿意的產品冰垄。
七、總結
寫到最后权她,我回過頭來看看虹茶,才發(fā)現對架構的整體認識站在了決策派的一邊,即這種共識便是在產品規(guī)劃隅要、設計蝴罪、開發(fā)階段一些重要方面所作出的決策的集合。這些決策是我們項目各個角色成員通過計劃會步清、評審會要门、迭代會等達成的共識虏肾,并最終表現在我們的產品上。產品欢搜、交互封豪、UI、開發(fā)炒瘟、測試吹埠,每個角色對自己所在領域負責的同時也需要隨時掌握其他領域的信息,以便自己做出正確的決策唧领。但是在對軟件技術實現的架構設計上藻雌,我就偏向了組成派,將軟件系統(tǒng)的業(yè)務進行了拆分和組合斩个,已達成系統(tǒng)運轉胯杭。我必須承認,此刻我的認識還是不夠通透受啥,在本文中各個方面大多還是泛泛而談做个,每個問題深入下去還有許多可以去研究的,希望能夠在以后的工作能夠有更深刻的領悟滚局。