高質(zhì)量代碼的三大要素:
可讀性、可維護(hù)性和可變更性
???做好代碼規(guī)范、提高代碼質(zhì)量,能顯著增強(qiáng)代碼的可讀性、可維護(hù)性和可變更性。本文將這三大要素合稱為代碼的讀寫可維護(hù)性,努力提高代碼的讀寫可維護(hù)性,是做好代碼規(guī)范的必要非充分條件。代碼規(guī)范和架構(gòu)設(shè)計(jì)是軟件的靈魂所在,代碼質(zhì)量偏低,就像是人失去了三魂七魄中的一魄,就會(huì)喪失活力,影響正常運(yùn)行,增加軟件交付后維護(hù)成本,出現(xiàn)推遲完成、超出預(yù)算、特性缺失等現(xiàn)象。
??? 任何語(yǔ)言都需要強(qiáng)調(diào)編碼風(fēng)格的一致性。只要是團(tuán)隊(duì)開發(fā),每個(gè)人都以相同的方式編寫代碼就是至關(guān)重要的。這樣大家才能方便地互相看懂和維護(hù)對(duì)方的代碼。
代碼規(guī)范
???如果不想為以后挖坑,做好代碼規(guī)范是程序員和團(tuán)隊(duì)負(fù)責(zé)人、項(xiàng)目經(jīng)理的必修課。如何保證當(dāng)前項(xiàng)目開發(fā)過(guò)程中壓力正常,而不是在后期面對(duì)過(guò)多的壓力、以至于噩夢(mèng)纏身?最簡(jiǎn)單的辦法就是照看好你的代碼,也就是落實(shí)好公司的代碼規(guī)范工作。每天為此付出一丁點(diǎn)的努力,便可以避免代碼「腐爛」,并保證代碼產(chǎn)品日后不至于變得難以理解(可讀性)和維護(hù)(可維護(hù)性)。
代碼的可讀性
代碼的可讀性是指代碼讓人容易閱讀、跟蹤和理解的程度。提高代碼的可讀性可以為代碼閱讀者節(jié)約時(shí)間(避免閱讀時(shí)浪費(fèi)過(guò)多無(wú)謂的時(shí)間)和精力(Debug、擴(kuò)展功能或是性能優(yōu)化的前提條件是你要讀懂這段代碼)。以下是摘選的可供參考的策略:
- 編碼風(fēng)格一致
- 代碼清晰表達(dá)意圖
- 寫人看得懂的單詞,如果選用英語(yǔ),那么避免日語(yǔ)、法語(yǔ)和漢語(yǔ)拼音等,盡量使用語(yǔ)義化的命名組合;
- PIE 原則:意圖清楚而且表達(dá)明確地編程;
- 能夠讓人快速看懂(最低限度的要求是自己一個(gè)月后能快速讀懂);
- 恰到好處的注釋
- 不能太多或太少,注釋的形式根
據(jù)代碼具體的情況有不同; - 避免用注釋包裹代碼;
- 盡量留下簡(jiǎn)明扼要的注釋;
- 不能太多或太少,注釋的形式根
- 評(píng)估取舍
- 避免寫一些現(xiàn)在不需要、將來(lái)也不太可能需要的功能:
- 不完美主義:不多寫代碼(如會(huì)話存儲(chǔ)拆分);
- 避免做沒(méi)有太大價(jià)值的優(yōu)化工作;
- 區(qū)分任務(wù)的輕重緩急:
- 頭疼醫(yī)頭也醫(yī)腳:先容忍失敗,再解決問(wèn)題(如節(jié)點(diǎn)關(guān)閉邏輯);
- 不頭疼不醫(yī)頭:量化分析(如參數(shù)調(diào)整回滾等);
- 綜合考慮一下性能、便利性、生產(chǎn)力、成本和上市時(shí)間……
- 簡(jiǎn)單就是美,避免簡(jiǎn)單的功能寫出復(fù)雜的代碼;
- 保持簡(jiǎn)單的代碼遠(yuǎn)比寫出復(fù)雜代碼要難得多,但這是值得的;
- 不編寫討巧的代碼;
- 避免無(wú)謂的條件嵌套和過(guò)度封裝;
- 第一眼看上去就能知道其用處的代碼,才是簡(jiǎn)單而美的代碼;
- 堅(jiān)持操作方法的原子性,而后使用組合模式實(shí)現(xiàn)業(yè)務(wù)邏輯;
- 避免大段代碼,要寫高內(nèi)聚、低耦合的代碼;
** 代碼的可維護(hù)性**
??軟件可維護(hù)性是指理解、改正、改動(dòng)、改進(jìn)軟件的難易程度。通常影響軟件可維護(hù)性的因素有可理解性、可測(cè)試性和可修改性。筆者這里將其分為兩大類:編寫時(shí)可維護(hù)性和運(yùn)行時(shí)可維護(hù)性。
編寫時(shí)可維護(hù)性
??編寫時(shí)可維護(hù)性是指在程序或系統(tǒng)上線后爆出 BUG,開發(fā)團(tuán)隊(duì)能夠及時(shí)撲滅這個(gè) BUG 且不會(huì)爆出其他 BUG。保持方法的原子性,提高代碼內(nèi)聚,能使某處修改的影響降到最低,這樣某處方法出現(xiàn) BUG,也不太會(huì)影響到其他模塊的正常運(yùn)作。編寫時(shí)可維護(hù)性還包括了代碼的「可測(cè)試性」。
??JavaScript Module AMD 標(biāo)準(zhǔn)執(zhí)行者(如 require.js)和 CMD 標(biāo)準(zhǔn)執(zhí)行者(如 sea.js)要求謹(jǐn)慎使用全局變量,將變量限制于一個(gè)個(gè)模塊之中,使得 JavaScript 代碼變得更有條理且更便于維護(hù)。
運(yùn)行時(shí)可維護(hù)性
??運(yùn)行時(shí)的可維護(hù)性是指在系統(tǒng)運(yùn)行過(guò)程中(或無(wú)需再次編碼發(fā)布、只需系統(tǒng)重啟一次)修改系統(tǒng)的某項(xiàng)配置并使其生效,且不影響現(xiàn)在正在進(jìn)行的業(yè)務(wù)和用戶的操作。這要求軟件工程師不能把代碼寫死。例如配置文件、數(shù)據(jù)庫(kù)連接字符串、資源文件、日志等。
代碼的可寫性
代碼的可寫性包括「代碼的可變更性」,代碼的可變更性是軟件理論的核心,OOSE 花了極大篇幅都在講軟件的變更;敏捷開發(fā)則天然地要求軟件產(chǎn)品具有高逼格的可變更性。
代碼的可寫性是建立在代碼的可維護(hù)性上的,而代碼的可寫性與可維護(hù)性又都建立在代碼的可讀性上。如果代碼難以閱讀,那么 BUG 的修正將變得難以入手,新功能的添加就更是無(wú)從入手了。
不過(guò)前人已經(jīng)為我們指明了許多方向,例如設(shè)計(jì)模式、RDD、TDD、DDD 等。使用設(shè)計(jì)模式可以顯著提高代碼的可寫性,盡管設(shè)計(jì)模式看上去難以理解且高深莫測(cè),但通過(guò)多閱讀優(yōu)秀代碼、優(yōu)秀框架,多通過(guò)社區(qū)、群、博客、郵件組和小面積聚會(huì)與在此道經(jīng)驗(yàn)富于己者交流,能讓自己的水平快速上升。最關(guān)鍵的是多實(shí)踐,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),也是掌握技術(shù)的唯一法門
「(程序員)富有探尋事物本質(zhì)之精神」便是此理。程序員幾乎無(wú)一例外地會(huì)將自己看到的能使自己進(jìn)步的知識(shí)與技巧立即(或不久之后)進(jìn)行嘗試(實(shí)踐)。
代碼重構(gòu)
代碼重構(gòu)是代碼可寫性的一種特殊情況,把不穩(wěn)定的積木塞塞緊。軟件開發(fā)的整個(gè)過(guò)程也是一個(gè)不斷迭代、不斷優(yōu)化、不斷重構(gòu)的過(guò)程。代碼重構(gòu)旨在不改變現(xiàn)有功能的基礎(chǔ)上,通過(guò)調(diào)整程序代碼改善軟件的質(zhì)量、性能,使其程序的設(shè)計(jì)模式和架構(gòu)更趨合理,提高軟件的擴(kuò)展性(可寫性)和維護(hù)性(可維護(hù)性)。
重構(gòu)的目的是最大限度避免軟件走向生命周期的終結(jié)(維護(hù)開發(fā)成本高于開發(fā)一個(gè)全新產(chǎn)品的成本時(shí),老的軟件便步入了生命周期的晚期)。通過(guò)不斷重構(gòu),糾正和改進(jìn)軟件設(shè)計(jì),使代碼更易為人所理解,有助于尋找到隱藏的代碼缺陷,使系統(tǒng)對(duì)新需求的變更保持較強(qiáng)的適應(yīng)能力(可寫性)。
關(guān)于重構(gòu)的知識(shí)就此打住,強(qiáng)烈建議感興趣的讀者購(gòu)買《重構(gòu):改善既有代碼的設(shè)計(jì)》和《大話重構(gòu)》這兩本書。
代碼檢查
代碼檢查應(yīng)采取自動(dòng)化檢測(cè)與人工代碼審查相結(jié)合的方式進(jìn)行,后者傾向于更為重要的設(shè)計(jì)錯(cuò)誤上(如 BUG、競(jìng)態(tài)條件和潛在死鎖等)。
代碼檢查的目的是理解代碼,改進(jìn)代碼,確保代碼能正常工作,而不是批評(píng)任何人。
關(guān)于代碼檢查清單,可以閱讀這篇文章;關(guān)于代碼審查的專業(yè)知識(shí)與技能不是本文關(guān)注的重點(diǎn),可以先閱讀這篇文章,然后購(gòu)買相關(guān)的專業(yè)書籍進(jìn)行學(xué)習(xí)。
編碼規(guī)范推薦
以下是一張可供參考的編碼規(guī)范示例。
垂直居中有幾種實(shí)現(xiàn)方式
方法1:table-cell
html結(jié)構(gòu):
1 <div class="box box1">
2 <span>垂直居中</span>
3 </div>
css:
1 .box1{
2 display: table-cell;
3 vertical-align: middle;
4 text-align: center;
5 }
方法2:display:flex
1 .box2{
2 display: flex;
3 justify-content:center;
4 align-items:Center;
5 }
方法3:絕對(duì)定位和負(fù)邊距
.box3{position:relative;}
.box3 span{
position: absolute;
width:100px;
height: 50px;
top:50%;
left:50%;
margin-left:-50px;
margin-top:-25px;
text-align: center;
}
方法4:絕對(duì)定位和0
1 .box4 span{
2 width: 50%;
3 height: 50%;
4 background: #000;
5 overflow: auto;
6 margin: auto;
7 position: absolute;
8 top: 0; left: 0; bottom: 0; right: 0;
9 }
這種方法跟上面的有些類似,但是這里是通過(guò)margin:auto和top,left,right,bottom都設(shè)置為0實(shí)現(xiàn)居中,很神奇吧。不過(guò)這里得確定內(nèi)部元素的高度,可以用百分比,比較適合移動(dòng)端。
方法5:translate
1 .box6 span{
2 position: absolute;
3 top:50%;
4 left:50%;
5 width:100%;
6 transform:translate(-50%,-50%);
7 text-align: center;
8 }
這實(shí)際上是方法3的變形,移位是通過(guò)translate來(lái)實(shí)現(xiàn)的。
方法6:display:inline-block
1 .box7{
2 text-align:center;
3 font-size:0;
4 }
5 .box7 span{
6 vertical-align:middle;
7 display:inline-block;
8 font-size:16px;
9 }
10 .box7:after{
11 content:'';
12 width:0;
13 height:100%;
14 display:inline-block;
15 vertical-align:middle;
16 }
這種方法確實(shí)巧妙...通過(guò):after來(lái)占位。
方法7:display:flex和margin:auto
1 .box8{
2 display: flex;
3 text-align: center;
4 }
5 .box8 span{margin: auto;}
方法8:display:-webkit-box
.box9{
display: -webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;
-webkit-box-orient: vertical;
text-align: center
}
方法9:display:-webkit-box
這種方法,在 content 元素外插入一個(gè) div。設(shè)置此 div height:50%; margin-bottom:-contentheight;。
content 清除浮動(dòng),并顯示在中間。
<div class="floater"></div>
<div class="content"> Content here </div>
.floater {
float:left;
height:50%;
margin-bottom:-120px;
}
.content {
clear:both;
height:240px;
position:relative;
}