技術(shù)團(tuán)隊(duì)中痛黎,財(cái)富即代碼,但并不是所有的代碼都是財(cái)富刮吧,有些代碼可能是毒藥湖饱。前段時(shí)間看到一篇文章,“你寫的代碼杀捻,是別人的噩夢(mèng)嗎井厌?”,雖然標(biāo)題針對(duì)我們技術(shù)人員來說致讥,可能有點(diǎn)刺耳仅仆,但有時(shí)候確實(shí)是不爭的事實(shí)。
在碼奴圈垢袱,有一句話很流行:“能運(yùn)行工作的代碼就是好代碼”墓拜。這句話沒有對(duì)與錯(cuò),在小的創(chuàng)業(yè)團(tuán)隊(duì)或人員能力不足的情況请契,能運(yùn)行工作的代碼確實(shí)是好代碼咳榜,因?yàn)樗鉀Q了我們當(dāng)時(shí)的問題。在對(duì)于有追求的技術(shù)人員來說爽锥,特別是在一個(gè)多人開發(fā)的團(tuán)隊(duì)中涌韩,產(chǎn)品功能在不停的迭代、優(yōu)化救恨,好代碼就會(huì)我們的開發(fā)效率與維護(hù)效率帶來成倍的提升贸辈。
何謂“好代碼”释树,每個(gè)人的答案其實(shí)是不一樣的肠槽。但說到“壞代碼”擎淤,大家應(yīng)該都能說出一籮筐來。
我先說一下我認(rèn)為的“壞代碼”:可讀性差秸仙、業(yè)務(wù)邏輯相互纏繞嘴拢、代碼復(fù)用性低,這樣帶來的后果將是隱藏bug寂纪、團(tuán)隊(duì)其他人員調(diào)用或維護(hù)難以入手席吴,更嚴(yán)重的可能就是重構(gòu)。有時(shí)候可能陷入不停的重構(gòu)循環(huán)當(dāng)中去捞蛋。原因有二:1.自己寫的代碼孝冒,沒有重構(gòu)到關(guān)鍵點(diǎn)上;2.下一個(gè)重構(gòu)者與上一個(gè)開發(fā)者不分伯仲拟杉。
那好代碼就是壞代碼的反面:可讀性強(qiáng)庄涡、業(yè)務(wù)邏輯低耦合高內(nèi)聚、代碼復(fù)用性高搬设、有良好的可拓展性穴店。
說了這么多,解決問題才是王道拿穴,如何才能按照上面說的好代碼的目標(biāo)開發(fā)泣洞,下面分享給大家一個(gè)容易入手的方法。
一默色、面向用例編程(橫向):
1.先把系統(tǒng)按照功能進(jìn)行劃分球凰,細(xì)化成多個(gè)功能模塊。做到每個(gè)模塊的功能是相對(duì)獨(dú)立的腿宰,但也有可能一個(gè)模塊與另一個(gè)模塊有交互弟蚀。
2.將功能需求進(jìn)行抽象,達(dá)到高內(nèi)聚酗失、低耦合的標(biāo)準(zhǔn)义钉,明確該功能模塊的參與者是什么。
3.對(duì)每一個(gè)功能模塊進(jìn)行業(yè)務(wù)分析规肴,看看是否能再按照子功能進(jìn)行細(xì)分捶闸,細(xì)分后形成具體的用例。
4.對(duì)具體用例進(jìn)行分析拖刃,理清用例與參與者的關(guān)系删壮、參與者與參與者的關(guān)系、以及用例與用例的關(guān)系兑牡。
將功能需求劃分成一個(gè)個(gè)獨(dú)立的用例后央碟,我們就能很清晰的表達(dá)功能需求的分離與組合。即先造一個(gè)個(gè)通用的輪子均函,然后對(duì)這些輪子按照業(yè)務(wù)需求進(jìn)行組裝亿虽。這樣就能達(dá)到有良好的組件顆粒度菱涤,很好的滿足了代碼結(jié)構(gòu)清晰、復(fù)用性強(qiáng)洛勉、組件可任意插拔粘秆、各個(gè)功能可以獨(dú)立測(cè)試(單元測(cè)試)的目標(biāo)。
面向用例編程的核心是把業(yè)務(wù)分解成一個(gè)個(gè)小的獨(dú)立的case(解耦)收毫,在根據(jù)業(yè)務(wù)需求將相關(guān)case聚集攻走、組裝在一起(內(nèi)聚)。最終又回歸到我們經(jīng)常說的低耦合此再、高內(nèi)聚的目標(biāo)之上昔搂。大到模塊劃分、小到函數(shù)定義输拇,都是同樣的方法巩趁。業(yè)務(wù)case集成一個(gè)模塊,功能函數(shù)聚集成一個(gè)類淳附。
面向用例編程也是封裝的一種體現(xiàn)议慰。將內(nèi)部邏輯封裝在一個(gè)盒子(case)里,對(duì)外只需要暴露接口奴曙。調(diào)用者也只需要關(guān)注接口别凹,不關(guān)心底層邏輯。
所以在我們開發(fā)之前洽糟,進(jìn)行業(yè)務(wù)建模炉菲,還是很重要的。
二坤溃、分層架構(gòu)(縱向)
上面說的面向用例編程是從橫向?qū)I(yè)務(wù)功能進(jìn)行解耦拍霜,那分層架構(gòu)就是從縱向上對(duì)功能職責(zé)的劃分。不論是后端開發(fā)薪介、前端開發(fā)還是客戶端開發(fā)祠饺,分層架構(gòu)很普遍。通常我們會(huì)在縱向上對(duì)項(xiàng)目進(jìn)行三層劃分:展示層汁政、業(yè)務(wù)邏輯層道偷、數(shù)據(jù)訪問層。MVC记劈、MVP勺鸦、MVVM都是為了更好的分層。
在團(tuán)隊(duì)成員中目木,經(jīng)常會(huì)有人質(zhì)疑分層换途,認(rèn)為有時(shí)候明明是一個(gè)很簡單的邏輯,非要搞幾層數(shù)據(jù)轉(zhuǎn)換,把結(jié)構(gòu)搞的比較復(fù)雜军拟。這個(gè)觀點(diǎn)也沒有錯(cuò)剃执,在生活中能用簡單的方法完成一件事情卻故意把事情搞的很復(fù)雜,確實(shí)是多此一舉吻谋。但我們通常是做一個(gè)復(fù)雜忠蝗、龐大且不停迭代更新的項(xiàng)目现横,功能業(yè)務(wù)可能會(huì)像網(wǎng)狀一樣交織在一起漓拾。如果沒有清晰的結(jié)構(gòu)、各個(gè)組件各司其職戒祠,如何能保證多人開發(fā)的團(tuán)隊(duì)敏捷高效的共同開發(fā)骇两,發(fā)現(xiàn)問題及時(shí)定位問題所在。
三姜盈、建立約束(規(guī)則)
約束即規(guī)范低千,團(tuán)隊(duì)成員按照一套統(tǒng)一的規(guī)范開發(fā),盡可能的降低溝通成本(了解現(xiàn)有代碼邏輯成本馏颂、業(yè)務(wù)調(diào)用成本示血、維護(hù)成本等)。約束包括一下幾個(gè)方面:
1.命名規(guī)范:按照規(guī)范進(jìn)行合理的命名救拉,BEAN难审、ENTITY、DTO亿絮、API等都分別代表不同的標(biāo)簽或職責(zé)告喊。看到名稱就知道它能做什么事情派昧。
2.分模塊黔姜、分包:每一個(gè)組件或包都有自己明確定義的職責(zé),不可以亂放蒂萎。presenter包只放Presenter秆吵,config包只放配置文件等。
3.統(tǒng)一的結(jié)構(gòu):項(xiàng)目主體要統(tǒng)一結(jié)構(gòu)五慈,堅(jiān)決不能出現(xiàn)相似業(yè)務(wù)不同代碼結(jié)構(gòu)帮毁,這樣只會(huì)讓參與項(xiàng)目的其他成員不知所錯(cuò)。
4.代碼檢查:如果有可能或有條件的話豺撑,通過工具或插件進(jìn)行項(xiàng)目代碼的檢查烈疚,可以是靜態(tài)的編譯檢查,也可以是動(dòng)態(tài)的運(yùn)行時(shí)檢查聪轿。
總之爷肝,建立約束,就是讓項(xiàng)目的參與者開發(fā)出來的代碼盡可能的保持風(fēng)格一致。
上面說了這么多灯抛,我們?cè)陂_發(fā)過程中金赦,只要代碼具有低耦合、高內(nèi)聚对嚼、可拓展夹抗、有良好的可讀性,就是給團(tuán)隊(duì)創(chuàng)造財(cái)富纵竖。
Android客戶端分層架構(gòu)實(shí)戰(zhàn)漠烧,F(xiàn)oolMVP。
一種MVP的實(shí)現(xiàn)方式靡砌,目標(biāo):代碼高度復(fù)用已脓、良好的組件顆粒度、方便進(jìn)行單元測(cè)試通殃,結(jié)構(gòu)盡量清晰簡單的高內(nèi)聚低耦合的分層結(jié)構(gòu)度液。