日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【笔记】编程的原则:改善代码质量的101个方法

發(fā)布時(shí)間:2024/3/7 编程问答 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【笔记】编程的原则:改善代码质量的101个方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

代碼必然被修改

Code will be changed

代碼不是寫完就結(jié)束了,它在日后必然會(huì)被修改。沒有寫完就扔的一次性代碼。

在編寫代碼的時(shí)候,我們應(yīng)將“代碼會(huì)被修改”這一點(diǎn)作為進(jìn)行判斷和選擇時(shí)的優(yōu)先考慮事項(xiàng)。

為什么?

軟件在本質(zhì)上具有復(fù)雜性,這就決定了它不可能是完美無缺的。軟件在發(fā)布后必然會(huì)發(fā)生故障,這時(shí)我們就需要對(duì)故障進(jìn)行修復(fù)。

另外,用戶可能在軟件發(fā)布后產(chǎn)生新的需求,因?yàn)橛行﹩栴}只有等到用戶實(shí)際使用軟件之后才能被發(fā)現(xiàn)。任何軟件都不可能在首次發(fā)布時(shí)就滿足用戶所有的需求。

除用戶自身之外,用戶所在商務(wù)環(huán)境的變化也會(huì)導(dǎo)致需求發(fā)生變化。軟件必須迎合這種變化。如果執(zhí)著于最初編寫的程序,做出沒有人用的軟件,那么一切都是徒勞。

怎么做?

編程中的任何一個(gè)判斷都要以代碼會(huì)被修改為前提。也就是說,編寫的代碼要經(jīng)得起修改。

因此,提高代碼的可讀性就顯得尤為重要了。代碼這種東西,讀遠(yuǎn)比寫要費(fèi)時(shí)間。如果以代碼會(huì)被修改為前提,那么不管寫代碼需要耗費(fèi)多少時(shí)間,只要讀代碼的時(shí)間能夠縮短,我們就能把消耗在寫代碼上的時(shí)間賺回來。

特別是接手其他人寫的代碼時(shí)尤為明顯,有一次我接手了一個(gè)反編譯后得到的.NET工程,由于是反編譯后得到的代碼,所以是沒有任何注釋的,當(dāng)時(shí)花了2,3天的時(shí)間才弄懂涉及到新需求的邏輯,之后為了完成需求而做出的修改所花費(fèi)的時(shí)間比閱讀代碼的時(shí)間少的多。要是代碼里有注釋應(yīng)該能節(jié)省不少時(shí)間。

KISS原則

Keep It Short And Simple(讓代碼保持整潔)

編寫代碼時(shí),要優(yōu)先保證代碼的簡(jiǎn)潔性。

不管是從零開始編寫代碼,還是修復(fù)故障或擴(kuò)展功能,都要注意保持代碼簡(jiǎn)潔。

為什么?

隨意修改代碼會(huì)使代碼變得越來越復(fù)雜,越來越?jīng)]有秩序。

復(fù)雜的代碼可讀性較差且難以修改。強(qiáng)行修改不僅會(huì)降低代碼的質(zhì)量,還會(huì)浪費(fèi)時(shí)間。這樣一來,我們就無法保證能在合適的時(shí)間發(fā)布修正版或者對(duì)軟件進(jìn)行更新。如果我們沒有重視這個(gè)問題,依舊強(qiáng)行修改代碼,代碼就會(huì)變得沒有人能看懂,最終腐化為無用之物。

而一份簡(jiǎn)潔的代碼,其各個(gè)組成要素也是簡(jiǎn)潔的,各要素承擔(dān)的職責(zé)也都降到了最小,各要素之間的關(guān)系也比較簡(jiǎn)單。因此,簡(jiǎn)潔的代碼可讀性高,容易理解,便于修改。各要素職責(zé)明確,使得測(cè)試也變得簡(jiǎn)單易行。程序員之間能更加輕松地通過代碼進(jìn)行交流,減少了在現(xiàn)實(shí)世界中多余的對(duì)話,節(jié)約了交流成本。這樣,我們就能保證在不降低開發(fā)速度的情況下對(duì)軟件進(jìn)行長(zhǎng)期維護(hù)。

代碼必然會(huì)被修改,因此易于修改的特性對(duì)代碼來說不可或缺。保持代碼簡(jiǎn)潔可以使代碼擁有易于修改的特性。

怎么做?

下面幾種情況會(huì)讓代碼變得復(fù)雜,應(yīng)該盡量避免:

1. 試圖使用新學(xué)會(huì)的技術(shù)

學(xué)會(huì)一門新技術(shù)后,人們傾向于使用新技術(shù)寫出一些無謂的代碼。

但是,代碼并不是用來炫耀聰明才智的,它的作用是給用戶提供價(jià)值。我們不能在代碼上耍聰明。

我們要多多斟酌代碼的寫法,努力保持代碼簡(jiǎn)潔。

2. 以備將來之需

有時(shí)人們覺得將來會(huì)用到某些功能,認(rèn)為最好趁現(xiàn)在寫下來,于是編寫了過剩的代碼。

現(xiàn)在用不到的東西就不應(yīng)該現(xiàn)在寫,因?yàn)樵诖蠖鄶?shù)情況下,這些東西將來也用不到。

我們應(yīng)該只寫當(dāng)前需要的代碼,保持代碼簡(jiǎn)潔。

3. 擅自增加需求

程序員有時(shí)會(huì)擅自增加需求,添加多余的代碼。他們覺得,某個(gè)需求必要與否、正確與否,與其找用戶確認(rèn),不如自己直接寫出來。但是,需求是由用戶決定的,程序員不可以擅自增加。

一旦添加了不必要的代碼,花費(fèi)在維護(hù)上的時(shí)間就會(huì)像滾雪球一樣增加。不寫多余的代碼是保證代碼簡(jiǎn)潔的秘訣。

DRY

Don't Repeat Yourself(不要重復(fù))

將整個(gè)邏輯隨便復(fù)制粘貼到其他地方去用是造成代碼重復(fù)的主要原因。這樣一來,同一個(gè)邏輯將出現(xiàn)在多個(gè)地方。

直接將常量寫入代碼也會(huì)造成代碼重復(fù)。如果意義相同的常量在多處使用,常量表達(dá)的信息就會(huì)重復(fù)出現(xiàn)多次。

為什么?

代碼一旦出現(xiàn)重復(fù),故障修復(fù)、添加功能等,代碼的改善措施就會(huì)變得難以實(shí)施。具體來說,我們會(huì)遇到以下困難:

1. 代碼的可讀性下降

相同的代碼出現(xiàn)多次,從量的角度來看是“代碼量變大”,從質(zhì)的角度來看是“復(fù)雜度變高”。顯然,代碼的可讀性會(huì)下降。

無法準(zhǔn)確理解代碼就無法確立修改方針。

2. 代碼難以修改

當(dāng)相同的代碼出現(xiàn)在多處時(shí),只有正確修改每一處代碼,才能確保整體的一致性。稍有不慎,修改就會(huì)出現(xiàn)遺漏。

另外,即使代碼完全相同,有時(shí)某些地方也用不著修改。在這種情況下,我們就需要閱讀前后代碼,判斷這一處是否需要修改。

若當(dāng)前重復(fù)的代碼之間存在細(xì)微差別,我們就需要更加深入地閱讀各個(gè)位置的代碼。控制語句的條件內(nèi)容或條件數(shù)量只要存在一點(diǎn)點(diǎn)差別,理解的難度就會(huì)進(jìn)一步增大。弄不好代碼會(huì)因無法解讀而得不到改善。

3. 沒有測(cè)試

出現(xiàn)重復(fù)的代碼大多是遺留代碼,也就是說,這部分代碼沒有經(jīng)過任何測(cè)試。

在沒有測(cè)試的狀態(tài)下,就算我們拼盡全力去修改遺留代碼,發(fā)生新故障的概率還是很大。

就算克服了上述所有困難,費(fèi)盡九牛二虎之力完成修改,這些代碼也會(huì)因?yàn)閯?dòng)了多個(gè)“大手術(shù)”而變得更加混亂。長(zhǎng)此以往,當(dāng)混亂蔓延至所有代碼時(shí),修改就會(huì)變成一個(gè)不可能完成的任務(wù)。

怎么做?

我們可以通過對(duì)代碼執(zhí)行抽象化操作來消除重復(fù)。

對(duì)代碼的邏輯執(zhí)行抽象化操作,其實(shí)就是給整個(gè)處理命名,將其函數(shù)化、模塊化。至于數(shù)據(jù),則需要起個(gè)名字定義為常量。最后將重復(fù)的部分全部置換為抽象后的內(nèi)容。

抽象化有以下幾個(gè)優(yōu)點(diǎn):

  • 減少了代碼量,減輕了閱讀負(fù)擔(dān)
  • 因?yàn)檫壿嫼蛿?shù)據(jù)有了名稱,所以代碼的可讀性變高了
  • 重復(fù)的代碼集中到了一處,我們只對(duì)這一處進(jìn)行修改即可。于是,代碼的修改操作變得簡(jiǎn)單,代碼的質(zhì)量也得到了保證
  • 抽象化的部分易于重復(fù)使用。在添加新功能的時(shí)候,重復(fù)使用代碼可以更快、更好地完成編程

不過,執(zhí)行抽象化操作需要我們跨越心理方面的障礙。比如將邏輯轉(zhuǎn)化為函數(shù)的操作就相當(dāng)費(fèi)時(shí)間,我們需要有足夠的耐心。另外,由于我們修改的是原本可以運(yùn)行的代碼,所以修改后的代碼存在不能正常運(yùn)行的風(fēng)險(xiǎn)。抽象化操作還有一個(gè)最明顯的缺點(diǎn),那就是太麻煩。

然而,避免重復(fù)這一點(diǎn)沒有商量的余地。從長(zhǎng)遠(yuǎn)看來,避免重復(fù)的利大于弊,這是歷史總結(jié)出來的結(jié)論。所以,即便要花時(shí)間重構(gòu),即便要花時(shí)間消除代碼不能正常運(yùn)行的風(fēng)險(xiǎn),即便操作起來有些麻煩,我們也要消除重復(fù)的代碼。

設(shè)計(jì)模式就是具有代表性的一種設(shè)計(jì)手法,它提供了代碼結(jié)構(gòu)模式以達(dá)到重復(fù)使用代碼的目的。從另一個(gè)方面來看,設(shè)計(jì)模式也可以說是一種防止重復(fù)思考(重復(fù)思考同一問題的解決方案)的手法。

性能調(diào)優(yōu)的箴言

Proverb of performance tuning

是什么?

所謂性能調(diào)優(yōu),就是編寫運(yùn)行速度快的代碼。性能調(diào)優(yōu)也稱為代碼優(yōu)化。

很多人認(rèn)為加快代碼的運(yùn)行速度是一件好事。但實(shí)際上,過早優(yōu)化代碼會(huì)產(chǎn)生各種問題。

因此,對(duì)于代碼優(yōu)化,我們要遵守以下規(guī)則。

① 不要在編程之初就對(duì)代碼進(jìn)行優(yōu)化

② 編程之初暫時(shí)不要對(duì)代碼進(jìn)行優(yōu)化(適用于專家)

代碼優(yōu)化并不是我們?cè)诰幊讨蹙蛻?yīng)該考慮的事情。在編程時(shí),我們要注意的是代碼的正確性和可讀性,編寫高質(zhì)量的代碼,而不是想方設(shè)法讓代碼的運(yùn)行速度變快。 

為什么?

優(yōu)化代碼需要我們付出無法接受的代價(jià)。即便完成優(yōu)化,代碼也會(huì)失去一些重要的東西,比如以下幾點(diǎn)。

1. 可讀性變低

優(yōu)化后的代碼肯定比優(yōu)化前的代碼更難懂。

因?yàn)閺男再|(zhì)上來說,優(yōu)化所做的工作是修改代碼中原本簡(jiǎn)單直接的邏輯。優(yōu)化代碼后,邏輯不再簡(jiǎn)單明快,變得難以表達(dá)意圖。也就是說,要提高性能,必須以失去邏輯清楚的設(shè)計(jì)和降低代碼的可讀性為代價(jià)。

最大限度優(yōu)化過的代碼非常難看,我們很難掌握它的處理過程。

2. 質(zhì)量變差

代碼復(fù)雜化會(huì)導(dǎo)致代碼的可讀性下降,從而降低代碼的質(zhì)量。在沒有明確描述算法過程的代碼中,故障很容易被漏掉。

不論回答的速度有多快,答不出正確答案也枉然。說得諷刺一點(diǎn),優(yōu)化在給代碼加入難以發(fā)現(xiàn)的新缺陷方面算是一種切實(shí)有效的方法。

3. 復(fù)雜度增大

優(yōu)化會(huì)利用特殊的后門強(qiáng)化模塊間的依賴性,提升代碼的結(jié)合度,讓代碼能夠利用一些平臺(tái)固有的功能。

用如此取巧的方式編寫代碼會(huì)增加代碼的復(fù)雜度,同時(shí)讓代碼失去可移植性。

慢慢地,代碼將越來越不符合優(yōu)質(zhì)代碼的條件。

4. 阻礙維護(hù)

代碼復(fù)雜化導(dǎo)致代碼的可讀性下降,從而提升了維護(hù)代碼的難度。

首先,問題難以被發(fā)現(xiàn),因?yàn)榇a優(yōu)化之后,不自然的描述會(huì)增加。這樣一來,我們就很難追蹤處理的流程了。也就是說,優(yōu)化后的代碼是高風(fēng)險(xiǎn)的危險(xiǎn)代碼。

再者,優(yōu)化還會(huì)對(duì)代碼的可擴(kuò)展性產(chǎn)生不好的影響。優(yōu)化是在給代碼設(shè)置更多前提條件的基礎(chǔ)上實(shí)現(xiàn)的。因此,優(yōu)化會(huì)限制代碼的通用性和可擴(kuò)展性。

5. 與環(huán)境相沖突

在大多數(shù)情況下,優(yōu)化只能在特定的環(huán)境中發(fā)揮作用。在某個(gè)特定環(huán)境下對(duì)代碼進(jìn)行優(yōu)化后,代碼在其他環(huán)境中運(yùn)行的效率可能會(huì)變低。

比如我們針對(duì)某個(gè)特定種類的處理器選用了最合適的數(shù)據(jù)類型。這種做法就可能會(huì)導(dǎo)致軟件在其他處理器上執(zhí)行的速度變慢。

6. 工作量增多

對(duì)代碼進(jìn)行優(yōu)化就等于多加了一項(xiàng)工作。

程序員要做的工作非常多。代碼如果能成功運(yùn)行起來,我們就應(yīng)該先去處理其他緊急的工作,而不是去對(duì)代碼進(jìn)行優(yōu)化。

優(yōu)化是一項(xiàng)非常耗時(shí)的工作。找到問題出現(xiàn)的原因并對(duì)代碼進(jìn)行優(yōu)化并不是一件容易的事情。一旦弄錯(cuò)優(yōu)化對(duì)象,就會(huì)浪費(fèi)大量寶貴的勞力。

怎么做?

我們要先寫高質(zhì)量的代碼,然后根據(jù)需要進(jìn)行優(yōu)化。

高質(zhì)量的代碼是在信息隱藏的原則下寫出來的。因?yàn)楦鱾€(gè)決定只會(huì)在局部范圍產(chǎn)生影響,所以代碼的修改不會(huì)影響到其他部分。先寫高質(zhì)量的代碼再調(diào)節(jié)性能效率更佳。

況且在大多數(shù)情況下,“高質(zhì)量”與“高性能”并不矛盾。按照上述優(yōu)先順序?qū)懗鰜淼拇a只要滿足高質(zhì)量代碼的要求,優(yōu)化時(shí)就不會(huì)產(chǎn)生多少新的工作。而且代碼質(zhì)量高,我們?cè)谧鎏砑庸ぷ鲿r(shí)也會(huì)輕松一些。

另外,寫完高質(zhì)量的代碼之后,如果要進(jìn)行優(yōu)化,一定要思考其必要性。優(yōu)化在很多時(shí)候不值得我們花費(fèi)那么多的時(shí)間和成本。是否進(jìn)行優(yōu)化,要在與解決故障、添加新功能和發(fā)布產(chǎn)品等重要工作相比較之后再?zèng)Q定。

影響軟件的性能的幾個(gè)因素:

從整體來看,除了代碼,軟件的性能還受到很多因素的影響。比如以下幾個(gè)因素。

  • 執(zhí)行環(huán)境
  • 部署的設(shè)置或者安裝的設(shè)置
  • 使用的中間件
  • 使用的庫(kù)
  • 相互運(yùn)用的舊系統(tǒng)
  • 架構(gòu)

這樣一看,一行一行的代碼對(duì)軟件整體的影響十分渺小。除了各行代碼之外,還有很多影響性能的因素。 

性能調(diào)優(yōu)的流程:

在實(shí)際工作中,很多時(shí)候我們會(huì)因?yàn)檐浖奶匦远枰獙?duì)代碼進(jìn)行優(yōu)化。

在對(duì)代碼進(jìn)行優(yōu)化(性能調(diào)優(yōu))時(shí),我們需要在流程方面遵守幾項(xiàng)規(guī)則。

1. 證明優(yōu)化的必要性

首先要再三確認(rèn)優(yōu)化的必要性。有時(shí)候用戶對(duì)某部分性能的需求并沒有程序員想的那么高。

2. 測(cè)量性能,找出瓶頸

確認(rèn)需要優(yōu)化后,我們要先找出瓶頸所在。

性能出現(xiàn)問題并不代表所有代碼的運(yùn)行速度都很慢,大多是某個(gè)特定部分占用了較長(zhǎng)時(shí)間。這個(gè)占去大部分處理時(shí)間的部分稱為“熱點(diǎn)”。

我們要全身心地尋找這個(gè)熱點(diǎn)。

3. 優(yōu)化瓶頸部分的代碼

發(fā)現(xiàn)熱點(diǎn)之后要對(duì)其進(jìn)行修改。

4. 測(cè)量性能,確認(rèn)優(yōu)化效果

不管是代碼優(yōu)化前還是代碼優(yōu)化后,我們都必須對(duì)性能進(jìn)行測(cè)量。

性能差的部分是無法推測(cè)出來的。優(yōu)化的效果也只能通過測(cè)量得知。

5. 驗(yàn)證優(yōu)化后的代碼是否存在運(yùn)行問題

優(yōu)化可能會(huì)使代碼出現(xiàn)一些新的問題。對(duì)代碼進(jìn)行優(yōu)化后,必須認(rèn)真檢查代碼是否存在運(yùn)行問題。

這里再說一下尋找熱點(diǎn)的方法。尋找熱點(diǎn)時(shí),應(yīng)利用分析工具,盡可能仔細(xì)且準(zhǔn)確地檢查代碼。

另外,由于優(yōu)化過程中要多次對(duì)代碼的性能進(jìn)行測(cè)量,所以為了提高效率,我們最好對(duì)這部分工作執(zhí)行自動(dòng)化處理。

一步一步走

One by one

是什么?

編程時(shí)要一次只做一件小事。

一件一件做,一點(diǎn)一點(diǎn)來,就像上臺(tái)階一樣一步一步走。不要一次性處理多項(xiàng)工作。

完成一個(gè)小任務(wù)后認(rèn)真檢查,沒有問題后再開始下一個(gè)任務(wù),如此循環(huán)。 

為什么?

一次處理一項(xiàng)工作的工作方式更有效率,最終產(chǎn)品的質(zhì)量也更好。

一步一步進(jìn)行編程,最后一步操作撤銷起來也會(huì)比較容易。

一步一步進(jìn)行編程,工作檢查起來也比較簡(jiǎn)單。

一步一步進(jìn)行編程,新舊代碼的替換也會(huì)更安全。

一步一步編程意味著程序員能夠掌握和控制代碼的狀態(tài)。這樣做能去除不確定因素,讓人安心工作。

在有心理壓力時(shí),人很難像平時(shí)一樣做出準(zhǔn)確的判斷。控制好自己的狀態(tài)也是寫出優(yōu)質(zhì)代碼的必要條件之一。

怎么做?

不一次性處理多項(xiàng)工作

邏輯思考的秘訣

關(guān)于邏輯思考,有幾個(gè)關(guān)鍵點(diǎn)需要我們了解。

  • 想立刻獲得答案的態(tài)度是不正確的。一眼看不出答案時(shí)應(yīng)當(dāng)繼續(xù)思考
  • 沒有經(jīng)過深思熟慮就下結(jié)論的做法是錯(cuò)誤的。發(fā)現(xiàn)某個(gè)東西可以滿足條件時(shí)不能想當(dāng)然,要探討其他的可能性
  • 避免反復(fù)思考同一件事
  • 直接用腦子思考有些困難,不如邊寫邊思考。邊寫邊思考能產(chǎn)生額外的效果。對(duì)于想不明白的地方,有時(shí)候?qū)懴聛硪豢淳兔靼琢?/li>
  • 直覺對(duì)邏輯思考來說也很重要。比如,當(dāng)我們感覺“創(chuàng)建矩陣有助于整理信息”時(shí),不妨先試一試。不過,直覺只能用在思考的過程中。僅憑直覺來獲取答案的行為只能說是瞎猜,這可不是一個(gè)好習(xí)慣

布魯克斯法則

是什么?

增員等于“火上澆油”

對(duì)于開發(fā)進(jìn)度滯后的軟件開發(fā)項(xiàng)目,如果為了趕進(jìn)度而在開發(fā)后半程添加人手,反而會(huì)使延遲情況進(jìn)一步加重。

在項(xiàng)目尾聲,當(dāng)我們發(fā)現(xiàn)產(chǎn)品無法如期交付時(shí),常會(huì)投入更多的人手。但這種做法只會(huì)火上澆油。

為什么?

人數(shù)和月數(shù)是無法交換的

項(xiàng)目的工時(shí)是用人數(shù)和月數(shù)換算的,也就是幾個(gè)人用幾個(gè)月完成某個(gè)項(xiàng)目,所以用“人數(shù)×月數(shù)”來計(jì)算項(xiàng)目工時(shí)。

這里要注意的是,該乘法運(yùn)算與數(shù)值的乘法運(yùn)算不同,人數(shù)和月數(shù)不能調(diào)換。也就是說,“人數(shù)×月數(shù)= 月數(shù)×人數(shù)”的式子是不成立的。

比如一個(gè)12人月的項(xiàng)目,客戶要求6個(gè)月內(nèi)開發(fā)完成,那么我們只要投入2人即可。如果人數(shù)和月數(shù)可以調(diào)換,那么當(dāng)客戶說這個(gè)項(xiàng)目比較急,需要在2個(gè)月之內(nèi)完成時(shí),我們只要投入6個(gè)人就行了。

然而在現(xiàn)實(shí)中,“6×2”和“2×6”并不相同。2人工作的效率與6人工作的效率不可同日而語。

理由如下。

1. 因存在依賴關(guān)系而產(chǎn)生額外的負(fù)擔(dān)

如果每個(gè)人的工作相互獨(dú)立,那么在人數(shù)是原來3倍的情況下,生產(chǎn)效率也會(huì)變?yōu)樵瓉淼?倍。

然而一般來講,工作分割之后,各項(xiàng)工作之間會(huì)產(chǎn)生依賴關(guān)系。

如此一來就會(huì)產(chǎn)生一些新的負(fù)擔(dān),如任務(wù)的分割、各項(xiàng)確認(rèn)工作的出現(xiàn)以及通信路徑的增加等。

即便追加人手,這些額外的負(fù)擔(dān)也會(huì)拖慢項(xiàng)目的進(jìn)度。

2. 培訓(xùn)新人會(huì)占用一定時(shí)間

在追加人手時(shí),為了能讓這些人發(fā)揮作用,必須讓他們學(xué)習(xí)當(dāng)前項(xiàng)目固有的各種知識(shí)、信息以及技術(shù)。也就是說,要花時(shí)間對(duì)新人進(jìn)行培訓(xùn)。此外,負(fù)責(zé)培訓(xùn)的人是同一個(gè)項(xiàng)目?jī)?nèi)的成員,這就導(dǎo)致新團(tuán)隊(duì)的整體生產(chǎn)效率下滑。

在新人真正發(fā)揮作用之前,整個(gè)項(xiàng)目的進(jìn)度都是滯后的。

怎么做?

重新制訂時(shí)間表

無條件地投入更多人手來趕上進(jìn)度是一種不明智的做法。

強(qiáng)行給當(dāng)前成員增加負(fù)擔(dān)也只會(huì)對(duì)項(xiàng)目造成損害。

進(jìn)度滯后最好的解決方法是重新制訂時(shí)間表。在此過程中,要與用戶做好協(xié)調(diào),同時(shí)決定各個(gè)功能的優(yōu)先程度,進(jìn)行階段式發(fā)布。

拓展:

人與人也不可交換

前面說過,人數(shù)與月數(shù)不可交換。從某種意義上講,人與人也是不可交換的。

一個(gè)程序員離開了,并不是再補(bǔ)一個(gè)程序員就行。之所以這么說,是因?yàn)槌绦騿T的水平參差不齊。

在物理空間內(nèi)的生產(chǎn)效率方面,有能力的人與沒能力的人之間的差距最多也就幾倍。但像程序員這種以信息空間為主戰(zhàn)場(chǎng)的人,由于不受物理方面的制約,各個(gè)程序員之間的生產(chǎn)效率有很大的差別。據(jù)說能差30倍。

不過,“同樣的時(shí)間內(nèi)能寫出多少代碼”這種生產(chǎn)效率上的差距并不是造成上述現(xiàn)象最根本的因素。某些方面的差距更根本且更巨大。

比如以下幾個(gè)方面。

  • 有能力 / 沒能力

有些人寫出的代碼能用,有些人寫出的代碼不能用。這是一個(gè)有與無的比較,計(jì)算差距已經(jīng)沒有意義了。

  • bug多 / bug少

有些人寫出的代碼沒有bug,有些人寫出的代碼到處都是bug。

二者的維護(hù)成本會(huì)出現(xiàn)巨大的差別。

  • 執(zhí)行速度快 / 執(zhí)行速度慢

有些人寫出的代碼執(zhí)行速度快,有些人寫出的代碼執(zhí)行速度慢。代碼的執(zhí)行速度慢意味著會(huì)浪費(fèi)用戶的時(shí)間。軟件的目的是實(shí)現(xiàn)業(yè)務(wù)的高效化,為用戶節(jié)省更多的時(shí)間。代碼執(zhí)行速度慢的話就違背了這一目的。

況且,代碼執(zhí)行速度慢還會(huì)引來用戶的投訴。這時(shí),我們不僅要花時(shí)間應(yīng)對(duì)用戶投訴,還會(huì)失去用戶的信任。

  • 代碼可讀性高 / 代碼可讀性低

有些人寫出的代碼可讀性高,有些人寫出的代碼可讀性低。

另外,有些人寫出的代碼便于修改,有些人寫出的代碼一經(jīng)修改就會(huì)出問題。

二者由此產(chǎn)生的優(yōu)化成本大不相同。代碼質(zhì)量差到一定程度時(shí)甚至無法優(yōu)化。

綜合上面幾點(diǎn)來看,有能力的程序員和沒能力的程序員確實(shí)差出好幾個(gè)檔次。

有能力的程序員在項(xiàng)目中起到的作用非常大。對(duì)于這些有能力的程序員,我們不可以將他們視為可交換的“1人月”,要把他們留在項(xiàng)目中承擔(dān)固定的職責(zé)。 

防御性編程

是什么?

防患于未然的程序設(shè)計(jì)

我們?cè)诰幊痰臅r(shí)候不要想當(dāng)然。

防御性編程與開車時(shí)的防御性駕駛是同一種思路。

在采取防御性駕駛這一駕駛方式的情況下,我們總抱有一種不知道其他駕駛員會(huì)做出什么事情的心態(tài)。也就是說,自己不認(rèn)為駕駛的過程是百分之百安全的,覺得中途可能會(huì)發(fā)生什么事。這樣一來,當(dāng)其他駕駛員做出一些危險(xiǎn)的行為時(shí),自己就能做好充分的準(zhǔn)備不受傷害。即便過失在其他駕駛員身上,自己的命也要由自己來保護(hù)。防御性駕駛體現(xiàn)的就是這樣一種心理。

與此類似,當(dāng)函數(shù)接收到非法數(shù)據(jù)時(shí),即便問題出在其他函數(shù)身上,我們也應(yīng)準(zhǔn)備好“防御性”的代碼以避免函數(shù)受到損害。為此,編程時(shí)要注意以下幾點(diǎn)內(nèi)容。

1. 確認(rèn)外部代碼傳來的數(shù)據(jù)輸入值(檢測(cè)“預(yù)想之內(nèi)的錯(cuò)誤”)

在從文件、用戶接口、網(wǎng)絡(luò)以及其他外部接口獲取數(shù)據(jù)時(shí),要確認(rèn)數(shù)據(jù)是否在合法范圍內(nèi)。比如檢查數(shù)值是否在有效范圍內(nèi)、字符串的長(zhǎng)度是否符合規(guī)定等。

盡量在較早的階段檢測(cè)出無效輸入。檢測(cè)出無效輸入后要迅速對(duì)其進(jìn)行適當(dāng)?shù)腻e(cuò)誤處理。

2. 確認(rèn)參數(shù)的值(檢測(cè)“預(yù)想之外的錯(cuò)誤”)

確認(rèn)其他函數(shù)傳來的參數(shù)的值。與檢測(cè)外部代碼傳來的數(shù)據(jù)不同,這里如果檢測(cè)出無效輸入,就意味著代碼存在bug。

我們可以使用斷言確認(rèn)參數(shù),在發(fā)現(xiàn)非法值時(shí)立刻停止程序。 

為什么?

開發(fā)與運(yùn)維中的“安全駕駛”

開發(fā)中的“安全駕駛”

提早發(fā)現(xiàn)非法數(shù)據(jù)能提升調(diào)試的效率,因?yàn)樘嵩鐧z測(cè)出非法數(shù)據(jù),并以明確的形式進(jìn)行通知,可以幫助我們立刻找到出現(xiàn)問題的地方。這樣一來,代碼的調(diào)查與修改都變得非常容易。

反過來,如果沒能提早檢測(cè)出非法數(shù)據(jù),那么故障就會(huì)蔓延到其他地方,這時(shí)我們就需要花費(fèi)更多的時(shí)間來尋找根本原因。

運(yùn)維中的“安全駕駛”

盡早處理非法數(shù)據(jù)能防止運(yùn)維中出現(xiàn)的問題進(jìn)一步擴(kuò)大。在較早的階段處理掉問題,能防止問題的蔓延。

錯(cuò)誤如果處理得不徹底就會(huì)蔓延到其他處理中,問題會(huì)變得越來越大。特別是當(dāng)錯(cuò)誤的數(shù)據(jù)進(jìn)入軟件深處時(shí),軟件的運(yùn)行可能會(huì)發(fā)生錯(cuò)誤,或者錯(cuò)誤的數(shù)據(jù)會(huì)進(jìn)入數(shù)據(jù)庫(kù)中,這將造成無法挽回的后果。

其中最棘手的當(dāng)屬安全問題。黑客在入侵系統(tǒng)時(shí),喜歡利用沒有徹底處理錯(cuò)誤的地方。可見,不完備的錯(cuò)誤處理也可能會(huì)成為安全漏洞。

怎么做?

路障戰(zhàn)術(shù)

我們需要采用“路障戰(zhàn)術(shù)”。建立路障,將損害控制在一定的區(qū)域內(nèi)。

船體由多個(gè)相互隔離的區(qū)域組成,這與路障戰(zhàn)術(shù)是同一種戰(zhàn)略思想。即便船撞上冰山,船體破損,只要隔離破損的區(qū)域,整個(gè)船體就不會(huì)有沉沒的危險(xiǎn)。

另外,建筑物中的防火墻與路障戰(zhàn)術(shù)也有異曲同工之妙。防火墻的作用在于防止火勢(shì)蔓延。

為了在代碼中建立路障,我們需要將特定的接口用作安全地帶與非安全地帶的分界線。檢驗(yàn)通過這條分界線的數(shù)據(jù),一旦發(fā)現(xiàn)非法數(shù)據(jù),立即采取適當(dāng)?shù)拇胧?/p>

這就好比手術(shù)室,所有東西都必須經(jīng)過消毒才能拿進(jìn)去。因此,通過大門進(jìn)入手術(shù)室的東西都是安全的。

以門(= 路障)為界,分界線的左側(cè)是“臟房間”,右側(cè)是“干凈的房間”。 

在代碼設(shè)計(jì)中,我們要明確“哪些東西可以進(jìn)入手術(shù)室”“哪些東西不能進(jìn)入手術(shù)室”,以及“門的位置”,也就是對(duì)安全地帶里面的模塊、安全地帶外面的模塊和在中間負(fù)責(zé)消毒的模塊進(jìn)行分工。

拓展1:

錯(cuò)誤處理的變種

對(duì)于預(yù)想之內(nèi)的錯(cuò)誤,不同的情況有不同的處理方式。具體來說有以下幾種處理方式。

  • 返回?zé)o害的值

在確認(rèn)某值無害的情況下,返回該值。

比如在數(shù)值計(jì)算的情況下返回0,在字符串計(jì)算的情況下返回空字符串,在指針計(jì)算的情況下返回NULL。

  • 使用下一個(gè)數(shù)據(jù)

在處理一連串?dāng)?shù)據(jù)的情況下,返回下一個(gè)有效數(shù)據(jù)。

以從數(shù)據(jù)庫(kù)讀取記錄為例,如果記錄無效,則一直讀取,直到發(fā)現(xiàn)有效記錄。

  • 返回和前面一樣的值

如果不會(huì)對(duì)結(jié)果造成重大影響,則返回和前面一樣的值。

以1秒內(nèi)讀取100次溫度計(jì)的代碼為例,如果其中有一次讀取失敗,在這種情況下,即使返回失敗前最后一次讀取的值,也不會(huì)有什么問題。

  • 使用近似值

在滿足一定的嚴(yán)密性的前提下,返回近似值。

比如在能顯示0℃~100℃的溫度顯示畫面中,溫度低于0℃時(shí)顯示0℃,高于100℃時(shí)顯示100℃。

  • 在日志中記錄警告信息

在日志文件中記錄警告信息后繼續(xù)執(zhí)行處理。

當(dāng)發(fā)生微小的錯(cuò)誤時(shí),忽略錯(cuò)誤繼續(xù)執(zhí)行處理有時(shí)是一個(gè)很好的選擇。不過,發(fā)生過的錯(cuò)誤一定要記錄下來。

  • 返回錯(cuò)誤

為了調(diào)用上游函數(shù)來處理錯(cuò)誤,我們要將檢測(cè)出來的錯(cuò)誤記錄在報(bào)告中。

在這種情況下,決定讓代碼的哪個(gè)部分負(fù)責(zé)處理錯(cuò)誤,哪個(gè)部分負(fù)責(zé)報(bào)告錯(cuò)誤就變得至關(guān)重要。

我們可以使用模塊的狀態(tài)變量、函數(shù)的返回值,或者通過拋出異常來報(bào)告錯(cuò)誤。

  • 調(diào)用錯(cuò)誤處理函數(shù)

錯(cuò)誤處理要交給共同的錯(cuò)誤處理函數(shù)來完成。

將錯(cuò)誤處理的責(zé)任一元化能降低調(diào)試的難度。不過,這個(gè)一元化的功能會(huì)使代碼整體產(chǎn)生較高的耦合度。因此,如果想把一部分代碼用到其他系統(tǒng)中,就需要連同錯(cuò)誤處理算法一起“搬家”。

  • 顯示錯(cuò)誤信息

在發(fā)生錯(cuò)誤的地方顯示錯(cuò)誤信息。

將錯(cuò)誤處理的開銷抑制到最小。不過,由于信息會(huì)分散在軟件各處,所以創(chuàng)建具有統(tǒng)一性的用戶接口、區(qū)分用戶接口與其他部分、將軟件轉(zhuǎn)換為其他語言等工作變得難以實(shí)施。

  • 終止處理

檢測(cè)到錯(cuò)誤后終止處理。

這個(gè)方法對(duì)重視安全性的軟件來說非常有效。在關(guān)鍵任務(wù)系統(tǒng)中,比起帶著錯(cuò)誤繼續(xù)處理,很多時(shí)候重新啟動(dòng)程序會(huì)比較好。

  • 各部分選擇最合適的方式處理錯(cuò)誤

選擇何種方式處理錯(cuò)誤,由負(fù)責(zé)設(shè)計(jì)與實(shí)現(xiàn)錯(cuò)誤發(fā)生部分的程序員來決定。

這給了程序員很大自由,但從軟件整體來看,錯(cuò)誤處理將失去統(tǒng)一性。

拓展2:

錯(cuò)誤處理中的“正當(dāng)性”和“堅(jiān)固性”

錯(cuò)誤處理中有“正當(dāng)性”和“堅(jiān)固性”兩種思路。

正當(dāng)性指一定不返回不正確的結(jié)果。與其返回不正確的結(jié)果,不如什么都不返回。

而堅(jiān)固性指為了讓軟件繼續(xù)運(yùn)行而不擇手段。即使會(huì)產(chǎn)生不正確的結(jié)果,也要讓軟件繼續(xù)運(yùn)行下去。

以哪種思路為先,就要看軟件的目的是什么了。

重視安全性的軟件要以正當(dāng)性為先。與其返回錯(cuò)誤結(jié)果,不如直接停止軟件。以醫(yī)療相關(guān)的管理軟件為例,相較于返回錯(cuò)誤結(jié)果繼續(xù)處理,通知錯(cuò)誤并停止軟件更能防止重大事故的發(fā)生。

而對(duì)于提供給用戶的軟件,堅(jiān)固性就要優(yōu)先于正當(dāng)性了。以文字處理軟件為例,比起軟件突然關(guān)閉導(dǎo)致大量寶貴的輸入數(shù)據(jù)丟失,帶著錯(cuò)誤繼續(xù)運(yùn)行所造成的損失更小。 

拓展3:

不忽視錯(cuò)誤代碼

不忽視錯(cuò)誤代碼是防御性編程的鐵則。

即使函數(shù)返回錯(cuò)誤代碼,接收方也有可能會(huì)忽視掉它。但是,我們一定要養(yǎng)成評(píng)價(jià)函數(shù)返回值的習(xí)慣。即便某個(gè)函數(shù)在理論上不會(huì)發(fā)生錯(cuò)誤,保險(xiǎn)起見我們也要對(duì)其進(jìn)行檢查。因?yàn)榉烙跃幊痰哪康木褪欠乐诡A(yù)料之外的情況出現(xiàn)。

自己編寫的函數(shù)不能忽視錯(cuò)誤,系統(tǒng)函數(shù)同樣不能。每次進(jìn)行系統(tǒng)調(diào)用都要檢查錯(cuò)誤代碼。

發(fā)現(xiàn)錯(cuò)誤之后,要在日志中輸出錯(cuò)誤編號(hào)以及錯(cuò)誤的詳細(xì)內(nèi)容。  

破窗效應(yīng)

是什么?

不好的代碼是“蟻穴”

如果大樓這類建筑物上有一扇長(zhǎng)期未被修理的窗戶,這棟大樓就會(huì)給人一種“被遺棄”的感覺。人們便不會(huì)再留心這棟大樓的狀態(tài)。

這樣的話,還會(huì)有窗戶繼續(xù)碎掉。接著是垃圾亂倒,滿墻涂鴉。別看只是破了一扇窗戶,如果放置不管,整棟建筑也會(huì)遭到嚴(yán)重的破壞。

軟件也會(huì)發(fā)生這樣的事情。如果對(duì)軟件的“破窗”,也就是那些不好的設(shè)計(jì)、錯(cuò)誤的決定或不好的代碼放置不管,那么不論它多么微不足道,也能在很短的時(shí)間內(nèi)讓整個(gè)軟件腐爛。

為什么?

不好的代碼會(huì)帶來邪念

軟件中一旦存在“破窗”,程序員的腦中就會(huì)不自覺地產(chǎn)生“剩下的代碼肯定也是一團(tuán)糟,隨便改一改算了”的想法。

關(guān)于這種現(xiàn)象,有一個(gè)叫作“信箱實(shí)驗(yàn)”的著名心理學(xué)實(shí)驗(yàn)。如果自家信箱附近的墻壁上有涂鴉,或者信箱附近有垃圾,那么該信箱中信件被盜的概率就會(huì)達(dá)到25%。僅僅是一些垃圾和涂鴉,就能將許多正直人士變成小偷。

除了從眾心理之外,我們也可以用“莫名的不安”這種心理來解釋為什么會(huì)出現(xiàn)這種現(xiàn)象。一扇被棄之不管的破窗戶,會(huì)讓人產(chǎn)生“在這附近遇到危險(xiǎn)的話肯定沒人來救”的想法,隨之讓人產(chǎn)生不安的情緒。即便是一些細(xì)枝末節(jié)的東西,如果總是以一種沒有得到處理的狀態(tài)擺在人們眼前,也會(huì)讓人漸漸變得神經(jīng)質(zhì),使人的交感神經(jīng)處于緊張狀態(tài), 甚至促使人付諸暴力。

也就是說,出現(xiàn)這種現(xiàn)象的關(guān)鍵原因,與其說是“破窗戶”本身,不如說是小小的問題被棄之不管而帶來的“不安”。相較于時(shí)間短強(qiáng)度大的精神壓力,人們對(duì)時(shí)間長(zhǎng)強(qiáng)度小的精神壓力更加敏感。當(dāng)某些有違社會(huì)道德的現(xiàn)象一直出現(xiàn)在我們的眼前時(shí),人就會(huì)暴露出脆弱性。

怎么做?

保持代碼整潔

我們不能對(duì)代碼的“破窗”,也就是代碼不好的部分放置不管,要在發(fā)現(xiàn)“破窗”的時(shí)候立即進(jìn)行修補(bǔ)。沒有了“破窗”,代碼就能保持整潔的狀態(tài),這樣一來,程序員便會(huì)小心翼翼地對(duì)待這些代碼,避免弄臟它們。就算交付日期近在眼前,也沒人愿意當(dāng)?shù)谝粋€(gè)弄臟代碼的人。

另外,如果沒有足夠的時(shí)間修復(fù)代碼,至少要簡(jiǎn)單明了地指出“這段代碼不好”。

比如對(duì)于自己認(rèn)為不好的地方,可以添加帶標(biāo)簽的注釋以顯示在IDE(Integrated Development Environment,集成開發(fā)環(huán)境)的任務(wù)列表里。這么做的目的是強(qiáng)調(diào)這些不好的地方已經(jīng)得到了管理,防止損害進(jìn)一步擴(kuò)大。

擴(kuò)展:

人會(huì)模仿人

破窗效應(yīng)既與“莫名不安”的心理因素有關(guān),也與“反射性模仿他人行為”的人類自身特性有關(guān)。

心理學(xué)中已經(jīng)證實(shí),人類在嬰兒時(shí)期就已經(jīng)具備“反射性模仿他人行為”的特性了。不過,這個(gè)特性需要有足夠長(zhǎng)的時(shí)間才會(huì)顯現(xiàn)出來。如果人們長(zhǎng)期處于一種低素質(zhì)的“習(xí)慣性懈怠”的狀態(tài),就會(huì)去模仿他人不好的行為,最終陷入惡性循環(huán),這也可能是破窗效應(yīng)出現(xiàn)的原因。

不過,不管是因?yàn)椤澳话病边€是“反射性模仿他人行為”,及時(shí)解決不好的代碼都是不變的應(yīng)對(duì)策略。

熵增原理

是什么?

代碼會(huì)自然而然地開始腐壞

熵是物理學(xué)術(shù)語,表示體系的混亂程度。根據(jù)熱力學(xué)法則,人們證明了全宇宙的熵處于增加狀態(tài)。

軟件開發(fā)可以超越大部分的物理法則,卻逃不出熵增原理的束縛。如果不對(duì)代碼進(jìn)行管理,其混亂程度就會(huì)不斷加深,直到突破極限。也就是說,代碼會(huì)逐漸轉(zhuǎn)向腐壞。 

為什么?

代碼會(huì)向著混亂的方向轉(zhuǎn)變

代碼變得越來越混亂是軟件開發(fā)中自然而然的事情。

不管開頭多么有序,只要過上一陣子,代碼就會(huì)開始腐壞。就像生肉放久了會(huì)變質(zhì)一樣,隨著時(shí)間的推移,代碼的腐壞程度會(huì)越來越深。臃腫的代碼越積越多,使得維護(hù)難度不斷增大。用不了多久,即便是很小的修改都需要耗費(fèi)大量勞力,迫使我們不得不重新設(shè)計(jì)軟件。

在這種情況下,重新設(shè)計(jì)軟件很難一帆風(fēng)順。如今的軟件日新月異,新的設(shè)計(jì)必須能跟得上時(shí)代的變遷才行。

也就是說,我們就算有非常明確的目標(biāo),也難免會(huì)跟不上步調(diào),因?yàn)槲覀冊(cè)趯?shí)際工作時(shí)打的是“移動(dòng)的靶子”。

怎么做?

抓住代碼腐壞的征兆

代碼開始腐壞時(shí)有幾個(gè)征兆。不要放過這些征兆,發(fā)現(xiàn)它們后立刻處理。

  • 刻板

刻板指不容易修改代碼。

僅僅因?yàn)橐惶幮薷?#xff0c;就需要對(duì)所有與其存在依賴關(guān)系的模塊進(jìn)行修改,我們稱這種代碼設(shè)計(jì)為刻板的設(shè)計(jì)。

刻板的設(shè)計(jì)會(huì)給我們帶來很多困擾。比如我們接到委托,要對(duì)代碼做一個(gè)很簡(jiǎn)單的修改,于是簡(jiǎn)單調(diào)查了需要修改的地方,預(yù)估了工作量。然而在實(shí)際工作時(shí),隨著工作的推進(jìn),我們還是要對(duì)其他預(yù)想之外的地方進(jìn)行修改。結(jié)果,工作量遠(yuǎn)遠(yuǎn)超出預(yù)估,我們只能在規(guī)模龐大的代碼中追查需要修改的地方。

  • 脆弱

脆弱指一處修改會(huì)對(duì)其他部分的代碼造成很大損害。脆弱的代碼甚至?xí)p壞與其完全不相關(guān)的代碼。因此,程序員在處理新問題時(shí)就可能會(huì)引發(fā)其他問題,這就使程序員陷入追著自己尾巴跑的狀態(tài)。

毫不夸張地說,脆弱的模塊并不罕見。這類模塊很容易辨認(rèn)。那些需要經(jīng)常修復(fù)的模塊、常年出現(xiàn)在故障列表中的模塊、程序員認(rèn)為需要重新設(shè)計(jì)的模塊,以及越修復(fù)質(zhì)量越差的模塊等就屬于脆弱的模塊。

  • 可移植性差

可移植性差指軟件難以移植到其他環(huán)境中。

如果軟件在任何環(huán)境下分離可運(yùn)行部分和依賴環(huán)境的部分都會(huì)出現(xiàn)困難并伴隨風(fēng)險(xiǎn),我們就可以說該軟件不具備可移植性。

  • 難以掌控

難以掌控指代碼難以掌控和開發(fā)環(huán)境難以掌控。

代碼難以掌控是指設(shè)計(jì)結(jié)構(gòu)不具備靈活性。我們無法在保持設(shè)計(jì)結(jié)構(gòu)的前提下輕松修改難以掌控的代碼。相較于能保持設(shè)計(jì)結(jié)構(gòu)的方法,使用投機(jī)取巧的方法更能輕松地完成修改。在代碼難以掌控的狀態(tài)下,做錯(cuò)事容易,做對(duì)事反而難。

而開發(fā)環(huán)境難以掌控常發(fā)生在開發(fā)環(huán)境效率低下的時(shí)候。比如,當(dāng)編譯需要花費(fèi)大量時(shí)間時(shí),即使我們知道已經(jīng)無法保持設(shè)計(jì)結(jié)構(gòu)了,還是會(huì)傾向于采用能避免大規(guī)模編譯的修改方式。如果提交確認(rèn)兩三個(gè)文件需要花費(fèi)好幾個(gè)小時(shí),我們就不會(huì)再思考保持設(shè)計(jì)結(jié)構(gòu)的方法了,而是會(huì)尋找更節(jié)約時(shí)間的修改方式。

  • 復(fù)雜

復(fù)雜指不必要的元素過多。

當(dāng)程序員預(yù)判規(guī)格說明書會(huì)發(fā)生變更,在代碼中事先埋下應(yīng)對(duì)機(jī)制時(shí),就容易使代碼變得復(fù)雜。這類做法總給人一種好的印象。很多人認(rèn)為預(yù)見未來并提早做出準(zhǔn)備就能保持代碼的靈活性,防止今后苦于修改。

然而很遺憾,這樣做只會(huì)帶來相反的效果。為應(yīng)對(duì)更多不測(cè),我們會(huì)在代碼中留下大量一次都用不上的結(jié)構(gòu)。這會(huì)讓代碼變得復(fù)雜,變得難以理解。

  • 重復(fù)

重復(fù)指同樣的代碼出現(xiàn)多次。

在寫文檔時(shí),復(fù)制粘貼是一個(gè)很好用的方法,但在編輯代碼時(shí),使用復(fù)制粘貼則會(huì)招來很嚴(yán)重的后果。在代碼出現(xiàn)重復(fù)的情況下,修改軟件將成為一項(xiàng)勞神費(fèi)力的工作。如果在重復(fù)的部分發(fā)現(xiàn)故障,就需要修改代碼中所有相同的部分。

況且,代碼有時(shí)候看上去相同,但實(shí)際上有著細(xì)微的差別,這時(shí)修改方式就可能不同了。

如果這種看上去相同但存在細(xì)微差別的代碼在軟件中大量出現(xiàn),就表示程序員沒有做抽象化工作。如果能找出所有重復(fù)的部分,將其適當(dāng)抽象化,消除重復(fù),系統(tǒng)將更容易理解且更容易維護(hù)。

  • 不透明

不透明指代碼難以理解。

代碼有時(shí)候很難讓人理解。而頻繁修改的代碼會(huì)隨著時(shí)間的流逝越來越難以讓人理解。

在剛寫完代碼時(shí),代碼對(duì)編碼者本人來說是非常明了的,因?yàn)榫幋a者沉浸于開發(fā),熟悉該項(xiàng)目的每個(gè)地方。然而過一段時(shí)間再回過頭來看,編碼者就會(huì)覺得自己怎么能寫出如此不堪的代碼。

為了防止此類情況發(fā)生,編碼者需要站在代碼閱讀者的立場(chǎng)思考,寫出別人能夠理解的代碼。讓別人來看自己寫的代碼是一個(gè)行之有效的方法。  

80-10-10原則

是什么?

編程沒有萬能藥

我們?cè)谟酶咚降墓ぞ呋蛘Z言開發(fā)軟件時(shí),可以在非常短的時(shí)間內(nèi)實(shí)現(xiàn)用戶80% 的需求。而在剩下20%的需求中,有10的需求需要通 過一定努力才能實(shí)現(xiàn),另10%則完全不可能實(shí)現(xiàn)。

因此,如果要100%滿足用戶的需求,開發(fā)就會(huì)陷入進(jìn)退兩難的境地。

如果此時(shí)已經(jīng)開發(fā)一部分內(nèi)容了,那么拋棄原有工具重新開發(fā)就顯得不切實(shí)際。這時(shí),我們就得放棄使用工具,用最笨拙的方式來滿足某部分需求。

為什么?

編程的問題領(lǐng)域太廣

軟件行業(yè)從20世紀(jì)90年代中期起,舉整個(gè)行業(yè)之力花費(fèi)十幾年做了一場(chǎng)實(shí)驗(yàn)。實(shí)驗(yàn)內(nèi)容是創(chuàng)造一款能夠讓能力平庸的技術(shù)人員的生產(chǎn)效率飛躍性提升的“萬能工具”,比如模型驅(qū)動(dòng)開發(fā)、4GL(第四代語言)等。

實(shí)驗(yàn)的結(jié)果顯示,使用單一工具很難在所有領(lǐng)域都獲得完美的成果。

人們創(chuàng)建這種工具是為了開發(fā)出更人性化、質(zhì)量更好的軟件。因此,為了防止能力平庸的技術(shù)人員引發(fā)問題,人們對(duì)語言施加了相當(dāng)強(qiáng)的功能限制。結(jié)果,工具產(chǎn)生了自己的“防守范圍”。

但軟件要處理的問題范圍是無限大的。用一個(gè)工具解決所有問題的“萬能藥”路線顯然走不通。

第二系統(tǒng)綜合征

是什么?

第二次發(fā)布總會(huì)出現(xiàn)功能過多的情況

由發(fā)布第一版軟件的程序員設(shè)計(jì)的第二版軟件會(huì)成為最危險(xiǎn)的一個(gè)版本。

第二版軟件有功能過多、質(zhì)量差以及功能的使用體驗(yàn)較差等傾向。

為什么?

人在適應(yīng)開發(fā)后會(huì)傾向于“多功能主義”

在開發(fā)第一版軟件時(shí),由于未知的情況很多,風(fēng)險(xiǎn)較高,所以我們?cè)谶M(jìn)行判斷時(shí)會(huì)比較慎重。即便想到了好的功能,也會(huì)留到下一次再實(shí)現(xiàn)。

然而,在開發(fā)第二版軟件時(shí),我們掌握了更多的信息,也有了自信,所以傾向于把之前保留的功能以及新想到的功能一股腦兒加進(jìn)去。

添加過多功能之后,代碼變得復(fù)雜,不易維護(hù)。功能本身也變得復(fù)雜,使用體驗(yàn)變差,結(jié)果添加的功能也沒能得到人們的青睞。不管是代碼還是實(shí)現(xiàn)的功能,質(zhì)量都較以前有所下降。

另外,那些暫時(shí)保留的功能在第一版軟件中也許是比較實(shí)用的,但在第二版軟件中,這些功能可能已經(jīng)失去了必要性,或者落后于時(shí)代了。也就是說,把這部分功能放到第二版軟件中實(shí)現(xiàn)是一種浪費(fèi)時(shí)間的做法。

怎么做?

考慮用戶

程序員要有自制力,避免陷入多功能主義的怪圈。

要做到這一點(diǎn),一個(gè)有效的做法就是重新對(duì)用戶進(jìn)行定義并將用戶具象化。此時(shí)不論是有意識(shí)的還是無意識(shí)的,程序員對(duì)用戶的印象都會(huì)對(duì)程序員的判斷產(chǎn)生影響。這就給程序員添加新功能的欲望帶上了“枷鎖”。

具體做法就是在編程時(shí)多想想以下問題。

  • 用戶是誰
  • 用戶需要什么
  • 用戶認(rèn)為什么是必要的
  • 用戶想要什么  

拓展:

第二系統(tǒng)后綜合征

前面說程序員容易在第二版軟件中產(chǎn)生多功能主義的傾向,但實(shí)際上,第二版以后的版本也會(huì)出現(xiàn)同樣的情況。

特別是數(shù)據(jù)包軟件等需要持續(xù)發(fā)布的軟件,隨著一次次版本升級(jí),沒用的功能會(huì)越來越多。

出現(xiàn)這種現(xiàn)象的原因可能是用戶群體不固定,程序員很難對(duì)用戶進(jìn)行具象化。而且功能一旦發(fā)布就很難有機(jī)會(huì)刪除,所以只能越積越多。

不可否認(rèn),添加功能可以提升軟件的魅力。但是,相較于新功能,用戶往往希望基本功能是穩(wěn)定的,或者基本功能的使用體驗(yàn)?zāi)艿玫礁纳啤!?/p>

功能蔓延:

功能的過分?jǐn)U張不能全部歸罪于程序員的一己私欲,毫無原則地滿足用戶的需求也是重要原因之一。

無條件滿足用戶的愿望,就會(huì)在軟件中增加大多數(shù)用戶用不到的功能,還要準(zhǔn)備用于控制該功能的復(fù)雜的設(shè)置畫面以及相關(guān)設(shè)置文件。如此一來,軟件就會(huì)變得難以維護(hù),故障頻出。

這種功能肆意增多的現(xiàn)象稱為功能蔓延(feature creep),該現(xiàn)象意味著軟件開始邁向破滅(或者已經(jīng)破滅了)。

軟件設(shè)計(jì)的終極之美是“簡(jiǎn)單”。越是簡(jiǎn)單優(yōu)質(zhì)且擁有眾多用戶的軟件,越容易出現(xiàn)更多的需求。如果忠實(shí)地滿足這些需求,將所有功能都開發(fā)出來,軟件將失去簡(jiǎn)單性,變成一款沒人用的軟件。這時(shí)我們就會(huì)陷入進(jìn)退兩難的窘境。

避免出現(xiàn)這種悲劇的關(guān)鍵是要有勇氣對(duì)需求說“NO”。對(duì)于那些與軟件核心無關(guān)、需要與其他軟件組合才能實(shí)現(xiàn)的功能,我們要明確地說“NO”。只有這樣,才能產(chǎn)生優(yōu)秀的設(shè)計(jì),才能讓軟件保持簡(jiǎn)單性。

不過,有時(shí)候我們很難拒絕用戶強(qiáng)烈的訴求。這時(shí),我們不要直接在軟件主體中實(shí)現(xiàn)該功能,而是要圍繞軟件主體進(jìn)行擴(kuò)展,或者以插件的形式在不改變軟件核心代碼的前提下修改軟件的運(yùn)行模式,以此來保持軟件主體的簡(jiǎn)單性。

重新發(fā)明車輪

是什么?

制作已有的東西

有時(shí)候?qū)τ谀撤N功能,明明有現(xiàn)成的代碼或庫(kù)可以使用,人們卻還要自己重新開發(fā)相同的功能。這就像專門花時(shí)間又重新發(fā)明一遍世上早就有的車輪一樣,是一種無用功。

有現(xiàn)成的東西,卻要去重新發(fā)明一個(gè),這是在浪費(fèi)時(shí)間。當(dāng)開發(fā)規(guī)模足夠大時(shí),其危害也是非常大的。想要一個(gè)“能運(yùn)行各種服務(wù)的服務(wù)器”,于是專門把Web 服務(wù)器這種規(guī)模極大的軟件重新開發(fā)了一遍。這種做法會(huì)浪費(fèi)非常多的時(shí)間。

而且在大部分情況下,相較于重新發(fā)明出來的東西,既有產(chǎn)品的質(zhì)量更好。比如相較于我們現(xiàn)寫出來的庫(kù),既有的標(biāo)準(zhǔn)庫(kù)更好,因?yàn)樗粌H能反映出提供標(biāo)準(zhǔn)庫(kù)的專家的知識(shí),還能反映出人們?cè)谑褂眠^程中積累的經(jīng)驗(yàn)。標(biāo)準(zhǔn)庫(kù)還有一個(gè)好處,那就是就算我們什么都不做,隨著時(shí)間的推移,其中的故障、功能和性能也會(huì)自行改善。

另外,如果忽視標(biāo)準(zhǔn)規(guī)格,根據(jù)自己的協(xié)議編寫代碼,將來就只能走自己的路線了。僅靠本地的幾個(gè)程序員是不可能跟得上世間的主流的。另外,由于所有的插口都是獨(dú)創(chuàng)的,所以將來也無法實(shí)現(xiàn)替換。 

 

為什么?

不知道車輪和想制作車輪

重新發(fā)明車輪的原因有以下兩種。

  • 不知道車輪

程序員不知道車輪的存在。也就是說,這種發(fā)明不是程序員有意而為的。

這歸咎于程序員的知識(shí)不足和學(xué)習(xí)不足。編寫與語言標(biāo)準(zhǔn)庫(kù)功能相同的代碼,或者在有標(biāo)準(zhǔn)協(xié)議的情況下用獨(dú)創(chuàng)的格式編寫通信功能的代碼等都屬于這種情況。

  • 想制作車輪

程序員有制作車輪的欲望。也就是說,這種發(fā)明是程序員有意而為的。

這是一種叫作“非我發(fā)明”(Not Invented Here,NIH)綜合征的問題。具體表現(xiàn)為某個(gè)東西原本沒有重新制作的必要,程序員卻出于對(duì)技術(shù)的興趣或排斥他人制作的東西而想重新制作一遍。

怎么做?

關(guān)注車輪之外的東西

我們要避免重新發(fā)明車輪,將重點(diǎn)放在本來應(yīng)該做的工作上。

為此,在編寫代碼之前,一定要先確認(rèn)是否存在相同功能的標(biāo)準(zhǔn)庫(kù)、開源庫(kù),是否存在標(biāo)準(zhǔn)協(xié)議等。

另外,要借助團(tuán)隊(duì)會(huì)議等機(jī)會(huì)從其他程序員處獲取信息。這樣就能避免團(tuán)隊(duì)內(nèi)出現(xiàn)重復(fù)勞動(dòng)的情況。

同時(shí),在團(tuán)隊(duì)中徹底清除利己主義的思想。

因?yàn)橄胱龆?#xff0c;這是程序員自私的一面。然而,軟件的目的不是滿足程序員的欲望,而是滿足用戶的需求。為了用戶,為了在質(zhì)量、開發(fā)時(shí)長(zhǎng)和費(fèi)用等方面做到最好,我們應(yīng)該時(shí)常調(diào)查哪些東西可供使用,掌握高質(zhì)量的開源工具或商用工具。 

拓展:

許重新發(fā)明車輪的情況

有時(shí)我們也需要大膽地重新發(fā)明車輪。

  • 商業(yè)目的

商業(yè)上的核心部分必須由自己制作。

在使用已有的東西時(shí),必然會(huì)對(duì)該部分產(chǎn)生依賴。依賴則意味著對(duì)該部分失去了控制權(quán)。

即便知道其中潛藏著致命的問題,我們也無法主動(dòng)去修改。就算可以委托他人修復(fù),何時(shí)能夠發(fā)布,是否真的能得到改善,都是未知數(shù)。質(zhì)量和交付期方面的問題很可能在商業(yè)上造成無可挽回的損害。

況且,使用已有的東西就意味著放棄該部分的“差別化”。因此,商業(yè)上的核心部分,從原則上來講都應(yīng)該由自己制作。只有自己制作出這部分內(nèi)容,并且花心思做出個(gè)性,從中積累經(jīng)驗(yàn),才能開發(fā)出獨(dú)特的、能貢獻(xiàn)于世界的軟件。

  • 學(xué)習(xí)目的

要成為優(yōu)秀的程序員,就得不斷積累高質(zhì)量的經(jīng)驗(yàn)。

軟件開發(fā)的模式、設(shè)計(jì)和編程等方面的好書有很多,然而讀書和實(shí)踐之間有很大的差別。

同樣,借用已有的代碼與自己從零設(shè)計(jì)、測(cè)試軟件,解決故障,提高軟件質(zhì)量得來的經(jīng)驗(yàn)有天壤之別。

不過,有機(jī)會(huì)編寫軟件核心部分代碼的程序員少之又少。大部分程序員只能借用已有代碼。在這種情況下,我們不知道代碼內(nèi)部是如何運(yùn)作的,因此和使用“黑箱”沒什么區(qū)別。

只看水面的話,我們是無法得知水下隱藏著何種危險(xiǎn)的。如果不知道水底究竟發(fā)生了什么,就不能靈活運(yùn)用水流。自己親手制作是一種必要的經(jīng)歷。為此而“重新發(fā)明車輪”是程序員學(xué)習(xí)、提高技術(shù)非常有效的一個(gè)方法。

當(dāng)然,我們免不了失敗,但這種經(jīng)歷也比直接拿現(xiàn)成的使用要寶貴。

親手從零開始寫代碼,進(jìn)行各種嘗試,從一次次失敗中學(xué)習(xí),能帶來不同于閱讀技術(shù)類圖書的好處。不過,讀書與實(shí)踐同等重要,它們對(duì)程序員來說都是不可或缺的。 

給牦牛剃毛

是什么?

抓不住問題的本質(zhì)

有種家畜叫牦牛。它是牛的一種,特征是身上長(zhǎng)著厚厚的毛。每當(dāng)臨近夏天,牦牛就需要剃毛。我們需要給牦牛剃去相當(dāng)多的毛才能讓它的皮膚露出來。

我們處理某些問題時(shí)就像給牦牛剃毛一樣,在解決問題的過程中總會(huì)有新的問題冒出來,讓我們難以抓住問題的本質(zhì)。

這種狀態(tài)如果持續(xù)太久,人們就可能會(huì)忘記原本要解決的問題是什么。

為什么?

問題會(huì)接二連三地出現(xiàn)

問題總是接二連三地出現(xiàn)。

假設(shè)我們想導(dǎo)入在Web 服務(wù)器上運(yùn)行的任務(wù)自動(dòng)化工具,以提高工作效率。

“先下載Web服務(wù)器程序。”

“文件太大了,沒有辦法下載。”

“那就導(dǎo)入下載工具。”

“下載工具怎么不運(yùn)行呀?”

“原來需要前置模塊啊。”

“那就下載前置模塊。”

“需要注冊(cè)用戶。”

“那就注冊(cè)一個(gè)吧。”

“誒?用戶注冊(cè)頁面不動(dòng)了。”

“原來是瀏覽器版本太老了。”

“升級(jí)了瀏覽器,注冊(cè)了用戶,模塊也下載好了。”

“怎么下載工具還是不運(yùn)行?”

“哎呀,需要操作系統(tǒng)的補(bǔ)丁包。”

(后面依然沒完沒了。)

這種像給牦牛剃毛一樣的情況會(huì)造成時(shí)間上的浪費(fèi)。有時(shí)候,就算我們預(yù)估了工作所需時(shí)間,也沒有辦法在預(yù)估的時(shí)間內(nèi)完成工作,這種情況發(fā)生的原因就是我們把時(shí)間耗費(fèi)在了給牦牛剃毛上。

另外,在給牦牛剃毛的狀態(tài)下,人非常容易積攢壓力。我們很難推測(cè)出需要花多長(zhǎng)時(shí)間才能把牦牛身上的長(zhǎng)毛剃光。如果這種無法達(dá)成目標(biāo)的狀態(tài)一直持續(xù)下去,人就會(huì)產(chǎn)生挫敗感。

怎么做?

盡早收手

當(dāng)我們發(fā)覺自己已經(jīng)陷入給牦牛剃毛的狀態(tài)時(shí),應(yīng)停下腳步,回想自己原本要實(shí)現(xiàn)的目標(biāo)是什么。如果發(fā)現(xiàn)自己已經(jīng)偏離了目標(biāo),或者從時(shí)間、成本的角度來看不適合再繼續(xù)操作下去了,應(yīng)立刻停止工作。因?yàn)樵谶@種情況下,尋找其他出路往往會(huì)帶來更好的結(jié)果。

另外,為防止其他人也陷入同樣的狀態(tài),我們應(yīng)將整個(gè)過程分享給團(tuán)隊(duì)成員。在一個(gè)全員共享的空間留下一份筆記,能夠防止他人浪費(fèi)時(shí)間。 

拓展:

勇于面對(duì)“給牦牛剃毛”

一般來說,見到要給牦牛剃毛的情況應(yīng)該繞著走。但是,出于一些有價(jià)值的目的,或者因?yàn)榫o急故障等,有時(shí)我們必須跨越“給牦牛剃毛”的障礙,解決問題。

這個(gè)時(shí)候最麻煩的是我們大腦解決問題的速度跟不上問題出現(xiàn)的速度。由于前一個(gè)問題尚未解決就冒出了下一個(gè)問題,所以我們的大腦在解決問題時(shí)往往像使用棧一樣,先讓問題入棧,再一個(gè)一個(gè)出棧解決(同時(shí)讓繼發(fā)的新問題入棧)。這就是給牦牛剃毛的狀態(tài)。在這種情況下,問題通常會(huì)接二連三地發(fā)生,出棧速度趕不上入棧速度,導(dǎo)致腦內(nèi)棧溢出。

為了防止這類情況的發(fā)生,我們要記住不能只在腦中解決問題。應(yīng)當(dāng)把問題寫下來,一個(gè)一個(gè)地解決。

編程中的“給牦牛剃毛”

給牦牛剃毛的情況常出現(xiàn)在搭建環(huán)境的過程中。不過,編程中也會(huì)遇到類似的情況。

比如,在寫代碼時(shí),由一個(gè)問題聯(lián)想到其他問題,離最初要解決的問題越來越遠(yuǎn)。在最壞的情況下,我們甚至?xí)涀畛趸蛑虚g想到的問題是什么。

又比如,在讀代碼時(shí),由于代碼未整理,所以我們很難找到當(dāng)初想知道的東西。在梳理錯(cuò)綜復(fù)雜的調(diào)用關(guān)系時(shí),一不小心就會(huì)忘記代碼讀到了哪里,或者讀代碼的目的是什么。

為防止這類情況發(fā)生,我們?cè)谧x寫復(fù)雜的代碼時(shí),要一邊做記錄一邊操作。特別是在寫代碼時(shí),我們需要思考的部分比實(shí)際操作的部分要多,不做記錄的話就可能會(huì)有陷入循環(huán)思考的狀態(tài)。

總結(jié)

以上是生活随笔為你收集整理的【笔记】编程的原则:改善代码质量的101个方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

国产精品久久久久久久婷婷 | 欧美日本在线视频 | 日韩videos| www.天天操 | 热久久精品在线 | 天天综合网天天 | 国产高清视频在线播放一区 | 在线性视频日韩欧美 | av字幕在线 | 亚洲免费永久精品国产 | 亚洲激情婷婷 | 国产99久久久精品 | 欧美精品久久天天躁 | 香蕉网在线播放 | 中文av免费 | 国产伦精品一区二区三区免费 | 国产一级二级视频 | 天天操偷偷干 | 午夜精品久久久99热福利 | 免费国产亚洲视频 | 久久精品网站视频 | 9在线观看免费高清完整版在线观看明 | 色人久久 | 99视频精品免费视频 | 天堂在线视频中文网 | 美女视频黄的免费的 | 欧美亚洲精品在线观看 | 一区二区精品在线视频 | 国产精品成| 黄色av一级片 | 成人久久久电影 | 特级毛片网 | 日韩理论在线 | 69xxxx欧美| 91精品网站 | 亚洲国产欧美一区二区三区丁香婷 | 久久av不卡 | 国产一区二区电影在线观看 | 久久久国产一区二区三区四区小说 | 91精品国产乱码 | 久久久久久久久久久免费 | 精品久久久久久久久中文字幕 | 成人在线免费观看视视频 | 美女视频黄免费 | 日韩欧美视频一区二区三区 | 97精品在线 | 日韩免费在线播放 | 欧美va天堂在线电影 | 在线视频免费观看 | 黄色网免费 | 91精品天码美女少妇 | 黄色免费视频在线观看 | 亚洲成人黄色在线 | 成人黄色电影在线播放 | 亚洲综合网站在线观看 | 国产中文字幕视频在线观看 | 国产精品99久久久精品免费观看 | 91丨九色丨首页 | 色姑娘综合 | 中文在线 | 免费在线观看av不卡 | 亚洲国产免费看 | 成人免费视频网站在线观看 | 国产精品一区在线观看 | 国产精品美女久久久免费 | 91视频在线观看大全 | 久久精品播放 | 亚洲精品美女在线观看播放 | 中文字幕日韩国产 | 91一区二区三区久久久久国产乱 | 久久艹影院 | 国产视频亚洲精品 | 中国一区二区视频 | 黄色av电影网| 精品国产亚洲在线 | 成年人免费在线播放 | 在线色资源 | 偷拍福利视频一区二区三区 | 久久成年人视频 | 九月婷婷色 | 精品一区91 | 国产亚洲欧美在线视频 | 97电影手机| 日韩性片 | 91香蕉视频 | 7777精品伊人久久久大香线蕉 | 色多视频在线观看 | 日韩av成人在线观看 | 免费欧美| 久久精品资源 | japanesexxxhd奶水| 91尤物国产尤物福利在线播放 | 欧美日韩国产综合一区二区 | 日韩av视屏在线观看 | 黄色的片子 | 97超在线 | 999久久久久| 日韩在线电影观看 | 天天骚夜夜操 | 在线观看视频你懂得 | 最新中文字幕在线播放 | av电影免费| 国产一级特黄毛片在线毛片 | 天天操天天操天天操天天操 | 黄色福利| 免费看国产精品 | 久久五月天综合 | 日韩黄色大片在线观看 | 国产精品手机在线播放 | 精品在线视频播放 | 国产福利久久 | 亚洲综合色视频在线观看 | 国产不卡免费av | 亚洲天堂激情 | 最近中文国产在线视频 | 国产精品毛片一区二区 | 青青草国产在线 | 久久久国产精品视频 | 亚洲一区天堂 | 日韩久久一区二区 | 91国内在线视频 | 少妇做爰k8经典 | 91精品电影 | 天天干视频在线 | 国产 欧美 日产久久 | 狠狠色噜噜狠狠 | 国内三级在线观看 | 福利电影一区二区 | 久久精品视频5 | 69av视频在线观看 | 天天综合天天做 | 国产在线一区二区三区播放 | 日本3级在线观看 | 狠狠干干 | 亚洲国产成人精品电影在线观看 | 91最新地址永久入口 | 91色在线观看 | 成人av电影免费在线播放 | 久久艹免费 | 免费在线观看不卡av | 国产一级三级 | 97色狠狠| 亚洲视频精选 | 色综合天天综合 | 亚洲精品白浆高清久久久久久 | 成人免费视频网址 | 一区在线观看 | 日韩va亚洲va欧美va久久 | 久色网 | 中文字幕免费播放 | 天天插天天射 | 在线视频一二区 | 免费高清在线观看成人 | 日韩一区二区三区免费视频 | 992tv在线成人免费观看 | 亚洲国产中文字幕在线 | 9久久精品 | 国产午夜三级一区二区三桃花影视 | 亚洲精品在线资源 | 97超碰人人澡 | 美国av大片 | 日韩在线观看视频在线 | 人人澡人人舔 | 天堂网中文在线 | 韩国中文三级 | avhd高清在线谜片 | 久要激情网 | 91香蕉视频色版 | 久久蜜桃av| av高清在线 | 亚洲欧美日韩不卡 | 国产玖玖精品视频 | 在线观看视频你懂的 | 久久伊人婷婷 | 成人av久久 | 天天插天天| 免费观看成人 | 久久久国产精品电影 | 日b黄色片 | 黄色免费国产 | 国产精品视频永久免费播放 | 国产一二区在线观看 | 久久久男人的天堂 | 日p在线观看 | 色综合久久66 | 亚洲精品视频在线免费 | 色视频一区 | av日韩在线网站 | 日韩一级电影在线观看 | 亚洲精品91天天久久人人 | 精品久久久久国产免费第一页 | 伊人va| 免费a级黄色毛片 | 毛片基地黄久久久久久天堂 | 国产精品久久久久三级 | 狠狠婷婷 | 国产xvideos免费视频播放 | 96av在线| av大全在线观看 | 日本公乱妇视频 | 国产精品视频免费看 | 久久久午夜精品福利内容 | 午夜.dj高清免费观看视频 | 在线观看不卡视频 | 久久av影院 | 国产免费一区二区三区网站免费 | 欧美人zozo | 欧美精品久久久久久久久久 | 精品在线观看一区二区 | 中文字幕av在线电影 | 亚洲免费av在线播放 | 欧美精品乱码99久久影院 | 精品久久久久久久久久岛国gif | a在线免费 | 美女视频a美女大全免费下载蜜臀 | 人人擦 | 少妇bbb | 久久久久成人精品 | 美女视频黄是免费的 | 91精品久久香蕉国产线看观看 | 日韩美精品视频 | 久久免费视频这里只有精品 | 免费一级特黄毛大片 | 久久精品aaa | 亚洲国产剧情av | 香蕉网址 | 国产精品欧美精品 | 在线视频久久 | 久久黄色精品视频 | 99视频在线观看一区三区 | 亚洲精品乱码久久久久v最新版 | 亚洲日日射 | 久久刺激视频 | 国产成人免费精品 | 日韩av一区二区在线影视 | 中文字幕国产精品一区二区 | 久久不见久久见免费影院 | 成人av免费在线观看 | 久久五月精品 | 菠萝菠萝在线精品视频 | 国产理论一区二区三区 | 久久看免费视频 | 久久久久久久久久影院 | 中文字幕网站视频在线 | 日韩视频在线不卡 | 综合网在线视频 | 久久精品96 | 亚洲精品美女久久 | 亚洲婷婷综合色高清在线 | 91精品国产自产老师啪 | 伊人手机在线 | 久久精品人人做人人综合老师 | 久久九九久久九九 | 国产手机在线视频 | 在线免费国产视频 | 国产午夜精品福利视频 | 色综合天天狠天天透天天伊人 | 国产色拍| 国产中文字幕在线 | 色5月婷婷| 狠狠躁天天躁 | 国产高清专区 | 黄色精品网站 | 在线免费av播放 | 波多野结衣精品视频 | 国内精品毛片 | 99精品视频免费观看视频 | 欧美另类成人 | 成 人 黄 色 视频 免费观看 | 久久日韩精品 | 日韩v在线 | 欧美日韩国产精品一区二区亚洲 | 精品字幕 | 亚洲成人免费观看 | 国产第一福利网 | 久久涩涩网站 | 九草视频在线观看 | 欧美日bb| 久久在线视频在线 | www.97视频 | 久久超碰免费 | 特及黄色片 | 特黄特色特刺激视频免费播放 | 日韩网站中文字幕 | 久久久久欠精品国产毛片国产毛生 | 伊人午夜 | 久草在线最新视频 | 97色在线观看 | 91丨九色丨高潮丰满 | 六月丁香婷婷久久 | 国产一级电影网 | 国产小视频在线免费观看视频 | 91在线免费视频观看 | 免费男女羞羞的视频网站中文字幕 | 国产精品一区二区三区久久久 | 免费亚洲视频在线观看 | 天天射天天搞 | 亚洲精品一区二区三区四区高清 | 久久9精品| 一区二区三区免费看 | 亚洲天堂网视频 | 中文字幕在线免费播放 | 狠狠干狠狠艹 | 91在线文字幕 | 国内外成人在线视频 | 精品久久久国产 | 干狠狠| 色网站中文字幕 | 激情综合网天天干 | 亚洲婷婷伊人 | 日韩在线观看第一页 | 91最新地址永久入口 | 欧美成亚洲 | 婷婷六月丁| 色视频网址 | 成人久久18免费网站 | 日韩av不卡在线播放 | 美女久久精品 | 久草a视频 | 色婷婷视频网 | 色综合人人 | 激情六月婷婷久久 | 国产精品不卡一区 | 国偷自产视频一区二区久 | 久久九九久久 | 国产精品视频你懂的 | 国产一区视频在线播放 | 在线成人免费av | 国产一级h| 国产精品久久久久免费 | 久久艹国产 | 免费av黄色 | 天天操综合网站 | 久久久久久高潮国产精品视 | 一级一级一片免费 | 国产综合精品一区二区三区 | 黄色一级在线观看 | 国产字幕在线观看 | 亚洲精品中文字幕在线 | 国产无套精品久久久久久 | 99精品视频播放 | 丁香激情综合 | 超碰在线亚洲 | 国产精品麻豆三级一区视频 | 很黄很污的视频网站 | 丁香 婷婷 激情 | 九九免费在线视频 | 亚洲精品影院在线观看 | 亚洲精品免费看 | 国产精品久久久久久久av大片 | 99色精品视频 | 成人一级片视频 | 人人爽人人射 | 成年人电影免费看 | 中文一区在线 | av黄色在线 | 国产999精品久久久 免费a网站 | 国产群p | 天天色天天上天天操 | 狠狠亚洲 | 国产免费久久精品 | 精品久久久久久久久中文字幕 | 999精品| 狠狠狠狠狠狠狠狠 | 男女激情免费网站 | 天天操天天色综合 | 国产午夜三级一区二区三桃花影视 | 不卡国产在线 | 成人四虎 | 欧美精品首页 | 亚洲精品91天天久久人人 | 久久艹中文字幕 | 91免费看片黄 | 久久精品导航 | 91成人网在线播放 | 香蕉精品视频在线观看 | 亚洲 欧洲 国产 日本 综合 | 日韩理论在线 | 国产尤物在线视频 | 成人欧美亚洲 | 国产精品久久久久久久免费观看 | 欧美在线91 | 中文字幕久久网 | 日本久久不卡视频 | 国产午夜小视频 | 波多野结衣在线播放一区 | 久久精品福利视频 | 久久亚洲精品电影 | 狠狠的操 | av一级免费 | 国产精品第一视频 | 久久免费av电影 | 9999精品免费视频 | 欧美视频二区 | 国产原创在线观看 | 97在线公开视频 | 7799av| 国产精品九九九九九 | 国产精品久久久久久a | 亚洲日本韩国一区二区 | 99中文字幕在线观看 | 天天综合入口 | 色婷婷色 | 视频91在线 | 国产福利一区二区三区视频 | 国语黄色片| 欧美日韩亚洲精品在线 | 国产专区在线视频 | 91av在线电影 | 日韩一区二区三 | 色资源网免费观看视频 | 精品在线小视频 | 国产精品中文 | 午夜色站| 日韩高清二区 | 日韩免费成人 | 亚洲日本国产精品 | 成人欧美日韩国产 | 91看片看淫黄大片 | 日韩欧美黄色网址 | 黄色三级在线观看 | 亚洲欧美视频在线 | 少妇搡bbbb搡bbb搡忠贞 | 一区二区三区四区久久 | 国产在线精品区 | 精品久久久免费视频 | 亚洲视频电影在线 | a级国产乱理论片在线观看 特级毛片在线观看 | 色福利网站 | 亚洲欧美日韩精品久久久 | 久久久久五月天 | 五月天激情视频 | 精品久久久久久国产91 | 中文字幕免费一区 | 六月丁香色婷婷 | 久久99精品久久只有精品 | 黄色91免费观看 | 久久精品牌麻豆国产大山 | 91黄色影视| 久久专区 | 亚洲天天看 | 午夜精品中文字幕 | 91精品视屏 | 97超碰资源 | 狠狠狠色丁香婷婷综合久久五月 | 99热国内精品 | 欧美激情操 | 国产午夜精品av一区二区 | 国产第一二区 | 黄色成年| 99在线高清视频在线播放 | 亚洲成成品网站 | 日韩av中文字幕在线免费观看 | 欧美日韩电影在线播放 | 香蕉在线观看 | 91在线九色 | 日日草天天草 | 日韩一区二区三区在线看 | 日韩视频免费观看高清 | 国产高清成人在线 | 亚洲激情五月 | 久久国产精品一区二区 | 五月婷婷狠狠 | 成人a在线观看高清电影 | 国产在线观看污片 | 日韩r级电影在线观看 | 成人免费视频免费观看 | 国产免费成人av | 国产黄色片网站 | 天天综合中文 | 久草精品电影 | 99视频偷窥在线精品国自产拍 | 国产福利精品视频 | 三级在线视频观看 | 91精品免费在线 | 免费激情在线电影 | 日狠狠 | 国产一级三级 | 久草免费看 | 在线观看黄色国产 | 国产精品欧美久久久久三级 | 在线观看中文字幕av | 天天se天天cao天天干 | 国产一区福利 | 国产午夜精品一区二区三区嫩草 | 综合亚洲视频 | 免费看国产视频 | 综合色中文 | 亚洲欧美精品在线 | 成人国产精品一区 | 亚洲理论电影网 | 国产在线播放一区 | 视频一区二区视频 | 久久色中文字幕 | 99久热在线精品 | 玖草在线观看 | 九九九在线观看 | 精品国产自 | 99精品国产成人一区二区 | 成人黄色大片在线观看 | a天堂最新版中文在线地址 久久99久久精品国产 | 久久草视频 | 在线观看免费日韩 | 国产日本在线 | 麻豆视频免费入口 | 2022中文字幕在线观看 | 久久久久成人精品免费播放动漫 | 国产区精品 | 成人av亚洲 | 黄色免费在线看 | 成人免费观看视频网站 | 亚洲精品成人av在线 | 色哟哟国产精品 | 999久久精品 | 在线视频免费观看 | 精品一区二区三区久久 | 日韩欧美极品 | 91精品国自产在线 | 色综合色综合久久综合频道88 | 亚洲综合爱 | 99热9| 51精品国自产在线 | 中文字幕在线国产 | 日韩在线第一区 | 一区二区三区在线播放 | 日本久热| 国产精品18videosex性欧美 | 中文字幕在线观看网 | 久久综合成人 | 亚州成人av在线 | 色综合色综合久久综合频道88 | 婷婷六月综合亚洲 | 欧美日韩免费一区二区 | 欧美在线aaa | 欧美日韩另类在线观看 | a天堂免费 | 激情九九 | 日韩精品一区二区三区外面 | 成人作爱视频 | 黄色国产高清 | 色a网| 在线观看免费中文字幕 | 亚洲天堂首页 | 黄色大片视频网站 | 美女视频黄在线 | 久久久久久久久毛片精品 | 特级aaa毛片| 日韩精品黄| 99色免费 | av在线免费观看不卡 | 四虎天堂| www.色com | 97超碰成人在线 | 精品国产精品一区二区夜夜嗨 | 久久久久成人精品 | 亚洲电影网站 | 十八岁以下禁止观看的1000个网站 | 日本高清xxxx | 天天爱天天 | www.色com| 国产美女在线精品免费观看 | 国产在线看一区 | 国产69精品久久99的直播节目 | 高清av影院 | 五月婷婷激情综合 | 黄色av网站在线观看免费 | 国产成人一级电影 | 69成人在线| 国产高清中文字幕 | 久久国产一区二区三区 | 最新中文字幕 | 91热这里只有精品 | 日韩精品免费在线 | 天天爽网站 | 99久久www免费 | 国产精品男女视频 | 国产精国产精品 | 色鬼综合网 | 97精品国产97久久久久久 | 国产高清在线永久 | 在线综合 亚洲 欧美在线视频 | 天天综合色 | 在线观看韩日电影免费 | 亚洲最新av网址 | 99精品欧美一区二区 | 天天艹天天 | 美女视频免费一区二区 | 婷婷六月丁香激情 | 中日韩欧美精彩视频 | 狠狠色丁香久久婷婷综合五月 | 国产一区二区视频在线 | 国产美腿白丝袜足在线av | 精品在线不卡 | 久久精品一 | 免费观看国产成人 | 国产精品丝袜在线 | 日韩中文字幕在线 | 中文字幕亚洲欧美日韩2019 | 国产视频午夜 | 久久99精品国产麻豆宅宅 | 特级西西444www高清大视频 | 久久成年人网站 | 在线www色 | 国产伦理精品一区二区 | 成人黄色在线 | 久久国产精品精品国产色婷婷 | 欧美性色综合网站 | 天天天操天天天干 | 免费观看91| av播放在线 | 免费av网址在线观看 | 狠狠色丁香婷婷综合久小说久 | 四虎影视国产精品免费久久 | 色婷婷97| 欧美激情第一区 | 久久毛片网 | 91精品国产乱码 | 国产麻豆精品传媒av国产下载 | 日韩精品一二三 | 麻豆高清免费国产一区 | 久久久视屏 | 日韩高清免费电影 | 首页国产精品 | 91麻豆精品国产91久久久久 | 91精品国产99久久久久久久 | 91麻豆视频 | 麻豆视频在线免费 | 色99视频 | av黄色在线观看 | 亚洲精品在线国产 | 免费av片在线 | 久久99国产精品久久 | 欧美精品做受xxx性少妇 | 国产丝袜制服在线 | 一级黄视频 | 91豆麻精品91久久久久久 | 色婷婷视频在线 | 九九有精品 | 中文 一区二区 | 久久综合五月天婷婷伊人 | 91九色精品| 天天干人人插 | 久久伊人热| 草草草影院 | 91手机视频在线 | 激情在线免费视频 | 国模视频一区二区 | 亚洲精品男人天堂 | 人人爽影院 | 中文字幕视频播放 | 久久丝袜视频 | 在线电影a| 日韩av视屏| 91九色精品女同系列 | 欧美日在线| 在线观看视频黄色 | 韩国av电影在线观看 | 久久综合国产伦精品免费 | 国产欧美最新羞羞视频在线观看 | 手机在线小视频 | 国产精品久久在线观看 | 欧美黑人巨大xxxxx | 91黄色视屏 | 久草视频免费在线观看 | 国偷自产中文字幕亚洲手机在线 | 亚洲精品美女免费 | 色综合久久88色综合天天免费 | 91九色视频在线观看 | 欧美精品在线观看免费 | 97视频在线观看免费 | www四虎影院 | 草久在线观看视频 | 久久午夜精品视频 | 亚洲视频综合在线 | 亚洲视频综合 | 免费激情在线电影 | 91视频免费网站 | 亚洲三级性片 | 一级黄色a视频 | 综合久久久久久 | 少妇精品久久久一区二区免费 | 成人午夜电影久久影院 | av三级在线播放 | 色香蕉网 | 亚洲国产成人高清精品 | 2019中文最近的2019中文在线 | 日日干激情五月 | av中文字幕剧情 | 中文字幕一区二区三区在线播放 | 国产精品高潮呻吟久久久久 | 在线免费精品视频 | 啪啪精品| 狠狠色丁香婷婷综合最新地址 | 色久综合| 三三级黄色片之日韩 | 亚洲一级电影 | 亚洲成人一二三 | 成人精品国产免费网站 | a爱爱视频| 最新亚洲视频 | 成人在线播放网站 | 成在人线av | 狠狠地日 | 国产亚洲精品久久久久久大师 | 最近中文字幕久久 | 五月婷亚洲 | 欧美一级片在线观看视频 | 97国产大学生情侣白嫩酒店 | 超碰在97 | 99热99 | 国产永久免费高清在线观看视频 | 国产午夜精品视频 | 91香蕉亚洲精品 | 少妇做爰k8经典 | 精品国产亚洲一区二区麻豆 | 亚洲激情网站免费观看 | 久久综合婷婷综合 | 人人讲下载 | 久色伊人 | 国产黄在线观看 | 日本在线观看一区二区三区 | 久久国产视屏 | 中文字幕在线日本 | 亚洲日本在线视频观看 | 免费在线观看成人av | 999久久久免费精品国产 | 欧美日韩调教 | 国内精品视频在线播放 | 国产精品久久久免费看 | av大全在线播放 | 欧美色婷婷 | 美女视频a美女大全免费下载蜜臀 | 久久精品3| 久久在线免费观看视频 | 欧美性天天 | 久久激情五月激情 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 视频一区二区三区视频 | 亚洲综合五月天 | 三级动图 | 国产亚洲精品久久久久秋 | 欧美午夜视频在线 | 久久精品亚洲精品国产欧美 | 亚洲在线精品视频 | 成人在线黄色电影 | 欧美午夜视频在线 | 特级西西444www大胆高清无视频 | 国产成a人亚洲精v品在线观看 | 在线播放你懂 | 激情欧美在线观看 | 在线观看黄色免费视频 | 国产精品一区二区av影院萌芽 | 日韩在线中文字幕 | 国产精品大片在线观看 | 久久综合影视 | 久久99精品国产一区二区三区 | 免费看黄的 | 久久视频| 国产精品成久久久久三级 | 日韩精品免费专区 | av不卡中文字幕 | 九九热视频在线播放 | 国产三级午夜理伦三级 | 国产麻豆精品一区二区 | 成年人免费电影在线观看 | 国产午夜精品免费一区二区三区视频 | 97超碰国产在线 | 国产青草视频在线观看 | 久久综合九色综合久久久精品综合 | 久久神马影院 | 中文字幕黄网 | 成人久久久久久久久久 | 久草在线最新视频 | 91麻豆传媒| 九九有精品 | 国产亚洲精品久久 | 中文字幕日本在线观看 | 国产精品美女在线观看 | 手机版av在线 | 91九色视频观看 | 一区二区三区在线免费 | 久久国产精品影片 | 国产在线永久 | 操处女逼| 久久欧美综合 | 热久久免费国产视频 | 亚洲第一区在线播放 | 黄色在线免费观看网址 | 四虎影视精品成人 | 成人三级网站在线观看 | 精品亚洲视频在线 | 97夜夜澡人人爽人人免费 | 综合网av | 欧美精品亚洲精品 | 国产色婷婷| 国产精品97| 婷婷在线观看视频 | 亚洲第一av在线 | 91免费观看视频网站 | 中文字幕婷婷 | 波多野结衣在线观看一区二区三区 | 成人免费视频a | 久久久免费看片 | 久久成熟 | 又黄又刺激的视频 | 亚洲春色综合另类校园电影 | 国产日本在线观看 | 久久久国产一区二区三区四区小说 | 久久99九九99精品 | 亚洲香蕉视频 | 九草在线视频 | 99久久99久久精品 | 在线观看www视频 | 偷拍精品一区二区三区 | 成人久久18免费 | 日日夜操 | av中文字幕在线播放 | 国产精品自在欧美一区 | 亚洲www天堂com | 亚洲欧美国产精品久久久久 | 国产视| 欧美成天堂网地址 | 99久久精品视频免费 | 日本女人的性生活视频 | 国产一区在线播放 | 人人爽人人爽人人片 | 日韩免费视频网站 | 久久久午夜精品理论片中文字幕 | 一区二区成人国产精品 | 精品一二三区视频 | 丁香六月婷婷综合 | 天天躁天天狠天天透 | 在线视频一二区 | 天天av资源| 91福利区一区二区三区 | 日韩中文字幕在线不卡 | 深夜国产福利 | 国产黄色观看 | 一区二区国产精品 | 视频精品一区二区三区 | 美女久久视频 | 香蕉影院在线播放 | 亚洲精品一区二区网址 | 日韩理论在线观看 | 亚洲成人av电影在线 | 日韩欧美xxx | av观看在线观看 | 99免费看片 | 欧美激情在线网站 | 免费观看成人 | 一区在线播放 | 操操操日日日 | 免费下载高清毛片 | 91在线视频观看 | 涩涩网站在线观看 | 精品国产乱码 | www夜夜| 在线亚洲午夜片av大片 | 中文字幕乱码日本亚洲一区二区 | 国产精品麻豆99久久久久久 | www.黄色片网站| 日韩精品专区 | 欧美人体xx | 91尤物国产尤物福利在线播放 | 91在线精品秘密一区二区 | 激情xxxx| 一区在线观看 | 狠狠狠色丁香综合久久天下网 | 国产精品中文久久久久久久 | 亚洲精品国精品久久99热 | 激情深爱| www.久久91| www亚洲视频 | 久草电影在线观看 | 国产精品高清av | 精品亚洲午夜久久久久91 | 欧女人精69xxxxxx | 91精品一区二区在线观看 | 久久精品亚洲国产 | 久久亚洲精品国产亚洲老地址 | 国产精品久久久久久久久久 | 成人全视频免费观看在线看 | 免费91在线 | 在线观看黄色免费视频 | 久久久久久久久影院 | 久久国产色 | 91九色丨porny丨丰满6 | 免费色视频在线 | 九九九毛片 | 操操操av | 97在线观看 | 亚洲国产精品日韩 | 亚洲天堂网在线观看视频 | 18国产精品福利片久久婷 | 国内精品久久久久久久97牛牛 | 欧美精品在线一区二区 | 午夜在线免费观看视频 | 国产一二三四在线视频 | 中文字幕免费高清 | 色网站在线免费观看 | 久草久热 | 欧美一级xxxx | 免费久久片| 精品影院 | 又色又爽又黄 | 天天天天射| 丁香综合五月 | 成片视频免费观看 | 亚洲精品乱码久久久久久蜜桃不爽 | 婷婷网五月天 | 婷婷色网| 久久精品国产一区二区三区 | 国产手机av| 99热精品国产 | 五月婷婷黄色网 | 黄网站污 | 免费看一级片 | 中文在线中文资源 | 国产视频精选 | 免费亚洲视频 | 91精品国产自产老师啪 | 国产午夜小视频 | 久久国产免 | 欧美性生交大片免网 | 中文字幕精品www乱入免费视频 | 91色蜜桃| 精品字幕在线 | 久久香蕉影视 | 国产涩图| 国产精品久久久精品 | 精品美女久久久久 | 久久草 | 视频国产| 激情 婷婷| 日韩av免费一区二区 | 91在线日本| 日韩一级网站 | 亚洲三级在线播放 | 欧美日韩精品在线观看 | 天天操狠狠操夜夜操 | av黄免费看| 九九九九热精品免费视频点播观看 | 午夜视频99| 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 中文字幕a∨在线乱码免费看 | 99久久精品免费看国产 | 欧美激情第28页 | 日韩视频免费 | 亚洲欧美日本一区二区三区 | 欧美激情xxxx性bbbb | 日韩在线观看一区二区三区 | 91在线欧美 | 在线电影日韩 | 亚洲精品成人av在线 | 精品国产一区二区三区日日嗨 | 激情偷乱人伦小说视频在线观看 | 国产69精品久久app免费版 | 综合亚洲视频 | 91系列在线 | 精品国产一区二区三区日日嗨 | 美女视频久久久 | 久久五月天婷婷 | 成人欧美一区二区三区黑人麻豆 | 国产又粗又猛又黄又爽 | 1024手机看片国产 | 亚洲精品久久久久中文字幕二区 | 伊人婷婷| 狠狠网亚洲精品 | 天天干天天操天天做 | 国产高清在线永久 | 亚洲精品啊啊啊 | 久久精品人人做人人综合老师 | 制服丝袜在线 | 四虎免费在线观看 | 香蕉视频网站在线观看 | 91在线观看视频网站 | 亚洲婷婷伊人 | 日韩精品久久久久久久电影99爱 | 国产精品嫩草在线 | 日韩久久久久久久久久久久 | 97精产国品一二三产区在线 | 欧美一级在线看 | 久久精品一区二区 | 国产精品国产三级国产不产一地 | 狂野欧美激情性xxxx欧美 | 500部大龄熟乱视频使用方法 | 久久99国产精品视频 | 亚洲经典视频在线观看 | 夜夜爽www| 超碰大片 | 国产91精品久久久久 | 久久久蜜桃 | 少妇av片 | 亚洲精品乱码久久久久久按摩 | 在线观看v片 | 顶级bbw搡bbbb搡bbbb | 精品久久国产一区 | 日韩免费视频 |