1、關(guān)心你的技藝
Care About Your Craft
除非你在乎能否漂亮地開發(fā)出軟件,否則其它事情都是沒有意義的。
2、思考!你的工作
Think!About Your Work
在你做某件事情的時(shí)候思考你在做什么。不間斷地思考,實(shí)時(shí)地批判你的工作。這將占據(jù)你的一些寶貴時(shí)間,酬勞則是更為活躍地參與你喜愛的工作、感覺到自己在掌握范圍日增的各種主題以及因感受到持續(xù)的進(jìn)步而歡愉。從長(zhǎng)遠(yuǎn)來說,你在時(shí)間上的投入將會(huì)隨著你和你的團(tuán)隊(duì)變得更為高效、編寫出更易于維護(hù)的代碼以及開會(huì)時(shí)間的減少而得到回報(bào)。
3、提供各種選擇,不要找蹩腳的借口
Provide Options,Don't Make Lame Excuses
不要說事情做不到;要說明能夠做什么來挽回局面。不要害怕提出要求,也不要害怕承認(rèn)你需要幫助。
4、不要容忍破窗戶
Don't Live With Broken Windows
不要留著“破窗戶”(低劣的設(shè)計(jì)、錯(cuò)誤的決策、或者糟糕的代碼)不修。發(fā)現(xiàn)一個(gè)就修一個(gè)。如果沒有足夠的時(shí)間進(jìn)行適當(dāng)?shù)男蘩恚扇?em>某種行動(dòng)防止進(jìn)一步的破壞,并說明情勢(shì)處在你的控制之下。
如果你發(fā)現(xiàn)你所在團(tuán)隊(duì)和項(xiàng)目的代碼十分漂亮——編寫整潔、設(shè)計(jì)良好,并且很優(yōu)雅,你不會(huì)想成為第一個(gè)弄臟東西的人。
5、做變化的催化劑
Be a Catalyst for Change
你不能強(qiáng)迫人們改變。相反,要向他們展示未來可能會(huì)怎樣,并幫助他們參與對(duì)未來的創(chuàng)造。
設(shè)計(jì)出你可以合理要求的東西,好好開發(fā)它。一旦完成,就拿給大家看,讓他們大吃一驚。然后說:“要是我們?cè)黾?..可能就會(huì)更好。”假裝那并不重要。坐回椅子上,等著他們開始要你增加你本來就想要的功能。人們發(fā)現(xiàn),參與正在發(fā)生的成功要更容易。讓他們瞥見未來,你就能讓他們聚集在你周圍。
6、記住大圖景
Remember the Big Picture
如果你抓一只青蛙放進(jìn)沸水里,它會(huì)一下子跳出來。但是,如果你把青蛙放進(jìn)冷水里,然后慢慢加熱,青蛙不會(huì)注意到溫度的緩慢變化,會(huì)呆在鍋里,直到被煮熟。
不要像青蛙一樣。留心大圖景。要持續(xù)不斷地觀察周圍發(fā)生的事情,而不只是你自己在做的事情。
7、使質(zhì)量成為需求問題
Make Quality a Requirements Issue
你所制作的系統(tǒng)的范圍和質(zhì)量應(yīng)該作為系統(tǒng)需求的一部分規(guī)定下來。讓你的用戶參與權(quán)衡,知道何時(shí)止步,提供足夠好的軟件。
8、定期為你的知識(shí)資產(chǎn)投資
Invest Regularly in Your Knowledge Portfolio
讓學(xué)習(xí)成為習(xí)慣。
持續(xù)投入十分重要。一旦你熟悉了某種新語言或新技術(shù),繼續(xù)前進(jìn),學(xué)習(xí)另一種。
是否在某個(gè)項(xiàng)目中使用這些技術(shù),或者是否把它們放入你的簡(jiǎn)歷,這并不重要。學(xué)習(xí)的過程將擴(kuò)展你的思維,使你向著新的可能性和新的做事方式拓展。思維的“異花授粉”十分重要;設(shè)法把你學(xué)到的東西應(yīng)用到你當(dāng)前的項(xiàng)目中。即使你的項(xiàng)目沒有使用該技術(shù),你或許也能借鑒一些想法。例如,熟悉了面向?qū)ο螅憔蜁?huì)用不同的方式編寫純C程序。
如果你自己找不到答案,就去找出能找到答案的人。不要把問題擱在那里。
9、批判地分析你讀到的和聽到的
Critically Analyze What You Read and Hear
不要被供應(yīng)商、媒體炒作、或教條左右。要依照你自己的看法和你的項(xiàng)目的情況去對(duì)信息進(jìn)行分析。
10、你說什么和你怎么說同樣重要
It's Both What You Say and the Way You Say It
作為開發(fā)者,我們必須在許多層面上進(jìn)行交流。我們的時(shí)間有很大部分都花在交流上,所以我們需要把它做好。
如果你不能有效地向他人傳達(dá)你的了不起的想法,這些想法就毫無用處。
知道你想要說什么;了解你的聽眾;選擇時(shí)機(jī);選擇風(fēng)格;讓文檔美觀;讓聽眾參與;做傾聽者;回復(fù)他人。
交流越有效,你就越有影響力。
11、DRY原則——不要重復(fù)你自己
DRY - Don't Repeat Yourself
系統(tǒng)中的每一項(xiàng)知識(shí)都必須具有單一、無歧義、權(quán)威的表示。與此不同的做法是在兩個(gè)或更多地方表達(dá)同一事物。如果你改變其中一處,你必須記得改變其它各處。這不是你能否記住的問題,而是你何時(shí)忘記的問題。
12、讓復(fù)用變得容易
Make it Easy to Reuse
你要做的是營(yíng)造一種環(huán)境,在其中要找到并復(fù)用已有的東西,比自己編寫更容易。如果復(fù)用很容易,人們就會(huì)去復(fù)用。而如果不復(fù)用,你們就會(huì)有重復(fù)知識(shí)的風(fēng)險(xiǎn)。
13、消除無關(guān)事物之間的影響
Eliminate Effects Between Unrelated Things
我們想要設(shè)計(jì)自足(self-contained)的組件:獨(dú)立,具有單一、良好定義的目的。如果組件是相互隔離的,你就知道你能夠改變其中一個(gè),而不用擔(dān)心其余組件。只要你不改變組件的外部接口,你就可以放心:你不會(huì)造成波及整個(gè)系統(tǒng)的問題。
你得到兩個(gè)主要好處:提高生產(chǎn)率與降低風(fēng)險(xiǎn)。
14、不存在最終決策
There Are No Final Decisions
沒有什么永遠(yuǎn)不變——而如果你嚴(yán)重依賴某一事實(shí),你幾乎可以確定它將會(huì)變化。與我們開發(fā)軟件的速度相比,需求、用以及硬件變得更快。通過DRY原則、解耦以及元數(shù)據(jù)的使用,我們不必做出許多關(guān)鍵的、不可逆轉(zhuǎn)的決策。有許多人會(huì)設(shè)法保持代碼的靈活性,而你還需要考慮維持架、部署及供應(yīng)商集成等領(lǐng)域的靈活性。
15、用曳光彈找到目標(biāo)
Use Tracer Bullets to Find the Target
曳光彈能通過試驗(yàn)各種事物并檢查它們離目標(biāo)有多遠(yuǎn)來讓你追蹤目標(biāo)。
曳光彈代碼含有任何一段產(chǎn)品代碼都擁有的完整的錯(cuò)誤檢查、結(jié)構(gòu)、文檔、以及自查。它只不過功能不全而已。但是,一旦你在系統(tǒng)的各組件之間實(shí)現(xiàn)了端到端(end-to-end)的連接,你就可以檢查你離目標(biāo)還有多遠(yuǎn),并在必要的情況下進(jìn)行調(diào)整。一旦你完全瞄準(zhǔn),增加功能將是一件容易的事情。
16、為了學(xué)習(xí)而制作原型
Prototype to Learn
任何帶有風(fēng)險(xiǎn)的事物。以前沒有試過的事物,或是對(duì)于最終系統(tǒng)極其關(guān)鍵的事物。任何未被證明的、試驗(yàn)性的、或有疑問的事物。任何讓你覺得不舒服的東西。都可以通過制作原型來研究。比如:架構(gòu);已有系統(tǒng)中的新功能;外部數(shù)據(jù)的結(jié)構(gòu)或內(nèi)容;第三方工具或組件;性能問題;用戶界面設(shè)計(jì)等等。
原型制作是一種學(xué)習(xí)經(jīng)驗(yàn),其價(jià)值并不在于所產(chǎn)生的代碼,而在于所學(xué)到的經(jīng)驗(yàn)教訓(xùn)。
17、靠近問題領(lǐng)域編程
Program Close to The Problem domain
計(jì)算機(jī)語言會(huì)影響你思考問題的方式,以及你看待交流的方式。用你的用戶的語言進(jìn)行設(shè)計(jì)和編碼。
18、估算,以避免發(fā)生意外
Estimate to Avoid Surprises
在著手之前先進(jìn)行估算。你將提前發(fā)現(xiàn)潛在的問題。
1)要選擇能反映你想要傳達(dá)的精確度的單位;
2)基本的估算訣竅:去問已經(jīng)做過這件事情的人;
3)理解提問內(nèi)容;
4)根據(jù)對(duì)問題的理解,建立粗略、就緒的思維模型骨架;
5)把模型分解為組件,找出描述這些組件怎樣交互的數(shù)學(xué)規(guī)則,確定每個(gè)組件的參數(shù);
6)給每個(gè)參數(shù)指定值,找出哪些參數(shù)對(duì)結(jié)果的影響最大,并致力于讓它們大致正確;
7)進(jìn)行多次計(jì)算,改變關(guān)鍵參數(shù)的值,然后根據(jù)那些參數(shù)表達(dá)你的答案;
8)在被要求進(jìn)行估算時(shí)說的話:“我等會(huì)回答你”。
19、通過代碼對(duì)進(jìn)度表進(jìn)行迭代
Iterate the Schedule with the Code
實(shí)行增量開發(fā)。追蹤你的估算能力,提煉對(duì)迭代次數(shù)、以及在每次迭代中可以包含的內(nèi)容的猜想。提煉會(huì)變得一次比一次好,對(duì)進(jìn)度表的信心也將隨之增長(zhǎng)。你將給予管理部門你所能給予的最精確的進(jìn)度估算。
20、用純文本保存知識(shí)
Keep Knowledge in Plain Text
保證不過時(shí);
杠桿作用:每一樣工具,都能夠在純文本上進(jìn)行操作;
更易于測(cè)試;
你需要確保所有各方能夠使用公共標(biāo)準(zhǔn)進(jìn)行通信。純文本就是那個(gè)標(biāo)準(zhǔn)。
21、利用命令shell的力量
Use the Power of Command Shells
GUI環(huán)境通常受限于它們的設(shè)計(jì)者想要提供的能力。當(dāng)你想要快速地組合一些命令,以完成一次查詢或某種其他的任務(wù)時(shí),命令行要更為適宜。多使用你的命令shell,你會(huì)驚訝它能使你的生產(chǎn)率得到怎樣的提高。
22、用好一種編輯器
Use a Single Editor Well
選一種編輯器,徹底了解它,并將其用于所有的編輯任務(wù)。如果你用一種編輯器進(jìn)行所有的文本編輯活動(dòng),你就不必停下來思考怎樣完成文本操縱:必需的鍵擊將成為本能反應(yīng)。編輯器將成為你雙手的延伸;鍵會(huì)在滑過文本和思想時(shí)歌唱起來。這就是我們的目標(biāo)。
23、總是使用源碼控制
Always Use Source Code Control
總是。即使你的團(tuán)隊(duì)只有你一個(gè)人,你的項(xiàng)目只有一周時(shí)間;確保每樣?xùn)|西都處在源碼控制之下。
源碼控制是你的工作的時(shí)間機(jī)器——你能夠回到過去。
把整個(gè)項(xiàng)目置于源碼控制系統(tǒng)的保護(hù)之下具有一項(xiàng)很大的、隱蔽的好處:你可以進(jìn)行自動(dòng)的和可重復(fù)的產(chǎn)品構(gòu)建。
24、要修正問題,而不是發(fā)出指責(zé)
Fix the Problem,Not the Blame
要接受事實(shí):調(diào)試就是解決問題,要據(jù)此發(fā)起進(jìn)攻。Bug是你的過錯(cuò)還是別人的過錯(cuò),并不是真的很有關(guān)系。它仍然是你的問題。
25、不要恐慌
Don't Panic
做一次深呼吸,思考什么可能是bug的原因。
要總是設(shè)法找出問題的根源,而不只是問題的特定表現(xiàn);
搜集所有的相關(guān)數(shù)據(jù);
開始修正bug的最佳途徑是讓其可再現(xiàn);
使你的數(shù)據(jù)可視化;
跟蹤:觀察程序或數(shù)據(jù)結(jié)構(gòu)隨時(shí)間變化的狀態(tài);
找到問題的原因的一種非常簡(jiǎn)單、卻又特別有用的技術(shù)是向別人解釋它。你只是一步步解釋代碼要做什么,常常就能讓問題從屏幕上跳出來,宣布自己的存在。
26、“Select”沒有問題
"Select" Isn't Broken
Bug有可能存在于OS、編譯器、或是第三方產(chǎn)品中——但這不應(yīng)該是你的第一想法。有大得多的可能性的是,bug存在于正在開發(fā)的應(yīng)用代碼中。與假定庫(kù)本身出了問題相比,假定應(yīng)用代碼對(duì)庫(kù)的調(diào)用不正確通常更有好處。即使問題確實(shí)應(yīng)歸于第三方,在提交bug報(bào)告之前,你也必須先消除你的代碼中的bug。
27、不要假定,要證明
Don't Assume it - Prove It
不要因?yàn)槟?#8220;知道”它能工作而輕易放過與bug有牽連的例程或代碼。證明它。在實(shí)際環(huán)境中——使用真正的數(shù)據(jù)和邊界條件——證明你的假定。
28、學(xué)習(xí)一種文本操作語言
Learn a Text Manipulation Language
你用每天的很大一部分時(shí)間處理文本,為什么不讓計(jì)算機(jī)替你完成部分工作呢?
應(yīng)用示例:
數(shù)據(jù)庫(kù)schema維護(hù);
Java、C#屬性(Property)訪問;
測(cè)試數(shù)據(jù)生成。
29、編寫能編寫代碼的代碼
Write Code That Writes Code
代碼生成器能提高你的生產(chǎn)率,并有助于避免重復(fù)。
30、你不可能寫出完美的軟件
You Can't Write Perfect Software
這刺痛了你?不應(yīng)該。把它視為生活的公理,接受它,擁抱它,慶祝它。因?yàn)橥昝赖能浖淮嬖凇T谟?jì)算機(jī)簡(jiǎn)短的歷史中,沒有一個(gè)人曾經(jīng)寫出過一個(gè)完美的軟件。你也不大可能成為第一個(gè)。除非你把這作為事實(shí)接受下來,否則你最終會(huì)把時(shí)間和精力浪費(fèi)在追逐不可能實(shí)現(xiàn)的夢(mèng)想上。
31、通過合約進(jìn)行設(shè)計(jì)
Design with Contracts
什么是正確的程序?不多不少,做它聲明要做的事情的程序。用文檔記載這樣的聲明,并進(jìn)行校驗(yàn),是按合約設(shè)計(jì)(簡(jiǎn)稱DBC)的核心所在。
這里,強(qiáng)調(diào)的重點(diǎn)是在“懶惰”的代碼上:對(duì)在開始之前接受的東西要嚴(yán)格,而允諾返回的東西要盡可能少。
使用DBC的最大好處也許是它迫使需求與保證的問題走到前臺(tái)來。在設(shè)計(jì)時(shí)簡(jiǎn)單地列舉輸入域的范圍是什么、邊界條件是什么、例程允諾交付什么——或者,更重要的,它不允諾交付什么——是向著編寫更好的軟件的一次飛躍。不對(duì)這些事項(xiàng)作出陳述,你就回到了靠巧合編程,那是許多項(xiàng)目開始、結(jié)束、失敗的地方。
32、早崩潰
Crash Early
死程序不說謊。
當(dāng)你的代碼發(fā)現(xiàn),某件被認(rèn)為不可能發(fā)生的事情已經(jīng)發(fā)生時(shí),你的程序就不再有存活能力。從此時(shí)開始,它所做的任何事情都會(huì)變得可疑,所以要盡快終止它。死程序帶來的危害通常比有問題的程序要小得多。
33、如果它不可能發(fā)生,用斷言確保它不會(huì)發(fā)生
If It Can't Happen,Use Assertions to Ensure That It Won't
斷言驗(yàn)證你的各種假定。在一個(gè)不確定的世界里,用斷言保護(hù)你的代碼。
不要用斷言代替真正的錯(cuò)誤處理。斷言檢查的是決不應(yīng)該發(fā)生的事情。
34、將異常用于異常的問題
Use Exceptions for Exceptional Problems
異常表示即使的、非局部的控制轉(zhuǎn)移——這是一種級(jí)聯(lián)的(cascading)goto。異常應(yīng)保留給意外事件。那些把異常用作其正常處理的一部分的程序,將遭受所有可讀性和可維護(hù)性問題的折磨。這些程序破壞了封裝:通過異常處理,例程和它們的調(diào)用者被更緊密地耦合在一起。
35、要有始有終
Finish What You Start
只要可能,分配某資源的例程或?qū)ο笠矐?yīng)該負(fù)責(zé)解除其分配。
36、使模塊之間的耦合減至最少
Minimize Coupling Between Modules
編寫“羞怯”的代碼;
函數(shù)的得墨忒耳(Demeter)法則規(guī)定,某個(gè)對(duì)象的任何方法都應(yīng)該只調(diào)用屬于以下情形的方法:
1)它自身;
2)傳入該方法的任何參數(shù);
3)它創(chuàng)建的任何對(duì)象;
4)任何直接持有的組件對(duì)象。
物理解耦。
37、要配置,不要集成
Configure,Don't Integrate
細(xì)節(jié)會(huì)弄亂我們整潔的代碼——特別是如果它們經(jīng)常變化。把它們趕出代碼。當(dāng)我們?cè)谂c它作斗爭(zhēng)時(shí),我們可以讓我們的代碼變得高度可配置和“軟和”——也就是,容易適應(yīng)變化。
要用元數(shù)據(jù)(metadata)描述應(yīng)用的配置選項(xiàng):調(diào)諧參數(shù)、用戶偏好(user preference)、安裝目錄,等等。
38、將抽象放進(jìn)代碼,細(xì)節(jié)放進(jìn)元數(shù)據(jù)
Put Abstractions in Code,Details in Metadata
但我們不只是想把元數(shù)據(jù)用于簡(jiǎn)單的偏好。我們想要盡可能多地通過元數(shù)據(jù)配置和驅(qū)動(dòng)應(yīng)用。我們的目標(biāo)是以聲明方式思考(規(guī)定要做什么,而不是怎么做),并創(chuàng)建高度靈活和可適應(yīng)的應(yīng)用。我們通過采用一條一般準(zhǔn)則來做到這一點(diǎn):為一般情況編寫程序,把具體情況放在別處——在編譯的代碼庫(kù)之外。
也許你在編寫一個(gè)具有可怕的工作流需求的系統(tǒng)。動(dòng)作會(huì)根據(jù)復(fù)雜的(和變化的)商業(yè)規(guī)則啟動(dòng)和停止。考慮在某種基于規(guī)則的系統(tǒng)(即專家系統(tǒng))中對(duì)它們進(jìn)行編碼,并嵌入到你的應(yīng)用中。這樣,你將通過編寫規(guī)則、而不是修改代碼來配置它。
39、分析工作流,以改善并發(fā)性
Analyze Workflow to Improve Concurrency
時(shí)間是軟件架構(gòu)的一個(gè)常常被忽視的方面。時(shí)間有兩個(gè)方面對(duì)我們很重要:并發(fā)(事情在同一時(shí)間發(fā)生)和次序(事情在時(shí)間中的相對(duì)位置)。
我們?cè)诰帉懗绦驎r(shí),通常并沒有把這兩個(gè)方面放在心上。當(dāng)人們最初坐下來開始設(shè)計(jì)架構(gòu),或是編寫代碼時(shí),事情往往是線性的。那是大多數(shù)人的思考方式——總是先做這個(gè),然后再做那個(gè)。但這樣思考會(huì)帶來時(shí)間耦合:方法A必須總是在方法B之前調(diào)用;同時(shí)只能運(yùn)行一個(gè)報(bào)告;在接收到按鈕點(diǎn)擊之前,你必須等待屏幕重畫。“嘀”必須在“嗒”之前發(fā)生。
這樣的方法不那么靈活,也不那么符合實(shí)際。
我們需要容許并發(fā),并考慮解除任何時(shí)間或者次序上的依賴。
40、用服務(wù)進(jìn)行設(shè)計(jì)
Design Using Services
實(shí)際上我們創(chuàng)建的并不是組件,而是服務(wù)——位于定義良好的、一致的接口之后的獨(dú)立、并發(fā)的對(duì)象。
通過把你的系統(tǒng)架構(gòu)成多個(gè)獨(dú)立的服務(wù),你可以讓配置成為動(dòng)態(tài)的。
41、總是為并發(fā)進(jìn)行設(shè)計(jì)
Always Design for Concurrency
首先,必須對(duì)任何全局或靜態(tài)變量加以保護(hù),使其免于并發(fā)訪問,現(xiàn)在也許是問問你自己、你最初為何需要全局變量的好時(shí)候。此外,不管調(diào)用的次序是什么,你都需要確保你給出的是一致的狀態(tài)信息。
在被調(diào)用時(shí),對(duì)象必須總是處在有效的狀態(tài)中,而且它們可能會(huì)在最尷尬的時(shí)候被調(diào)用。你必須確保,在任何可能被調(diào)用的時(shí)刻,對(duì)象都處在有效的狀態(tài)中。這一問題常常出現(xiàn)在構(gòu)造器與初始化例程分開定義的類中(構(gòu)造器沒有使對(duì)象進(jìn)入已初始化狀態(tài))。
一旦你設(shè)計(jì)了具有并發(fā)要素的架構(gòu),你可以靈活地處理應(yīng)用的部署方式:?jiǎn)螜C(jī)、客戶-服務(wù)器、或是n層。
42、使視圖與模型分離
Separate Views from Models
也就是常說的MVC模式(Model-View-Controller)。
模型。表示目標(biāo)對(duì)象的抽象數(shù)據(jù)模型。模型對(duì)任何視圖或控制器都沒有直接的了解。
視圖。解釋模型的方式。它訂閱模型中的變化和來自控制器的邏輯事件。
控制器。控制視圖、并向模型提供新數(shù)據(jù)的途徑。
通過松解模型與視圖/控制器之間的耦合,你用低廉的代價(jià)為自己換來了許多靈活性。
43、用黑板協(xié)調(diào)工作流
Use Blackboards to Coordinate Workflow
用黑板協(xié)調(diào)完全不同的事實(shí)和因素,同時(shí)又使各參與方保持獨(dú)立和隔離。
現(xiàn)代的分布式類黑板(blackboard-like)系統(tǒng),比如JavaSpaces和T Spaces。
44、不要靠巧合編程
Don't Program by Coincidence
總是意識(shí)到你在做什么。
不要盲目地編程。試圖構(gòu)建你不完全理解的應(yīng)用,或是使用你不熟悉的技術(shù),就是希望自己被巧合誤導(dǎo)。
按照計(jì)劃行事。
依靠可靠的事物。如果你無法說出各種特定情形的區(qū)別,就假定是最壞的。
為你的假定建立文檔。“按合約編程”有助于澄清你頭腦中的假定,并且有助于把它們傳達(dá)給別人。
不要只是測(cè)試你的代碼,還要測(cè)試你的假定。
為你的工作劃分優(yōu)先級(jí)。
不要做歷史的奴隸。不要讓已有的代碼支配將來的代碼。
所以下次有什么東西看起來能工作,而你卻不知道為什么,要確定它不是巧合。
45、估算你的算法的階
Estimate the Order of Your Algorithms
在你編寫代碼之前,先大致估算事情需要多長(zhǎng)時(shí)間。
46、測(cè)試你的估算
Test Your Estimates
對(duì)算法的數(shù)學(xué)分析并不會(huì)告訴你每一件事情。在你的代碼的目標(biāo)環(huán)境中測(cè)定它的速度。
47、早重構(gòu),常重構(gòu)
Refactor Early,Refactor Often
在需要時(shí)對(duì)代碼進(jìn)行重寫、重做和重新架構(gòu)。要鏟除問題的根源。不要容忍破窗戶。
關(guān)于重構(gòu),詳見Martin Fowler的《重構(gòu)》一書。
48、為測(cè)試而設(shè)計(jì)
Design to Test
在你還沒有編寫代碼時(shí)就開始思考測(cè)試問題。測(cè)試驅(qū)動(dòng)開發(fā)?
49、測(cè)試你的軟件,否則你的用戶就得測(cè)試
Test Your Software,or Your Users Will
測(cè)試是技術(shù),但更是文化。一點(diǎn)預(yù)先的準(zhǔn)備可以大大降低維護(hù)費(fèi)用、減少客戶服務(wù)電話。
50、不要使用你不理解的向?qū)Тa
Don't Use Wizard Code You Don't Understand
向?qū)Ш芰瞬黄稹V恍枰c(diǎn)擊一個(gè)按鈕,回答一些簡(jiǎn)單的問題,向?qū)Ь蜁?huì)自動(dòng)為你生成骨架代碼(skeleton code)。但如果你使用向?qū)В瑓s不理解它制作出的所有代碼,你就無法控制你自己的應(yīng)用。你沒有能力維護(hù)它,而且在調(diào)試時(shí)會(huì)遇到很大的困難。
51、不要搜集需求——挖掘它們
Don't Gather Requirements - Dig for Them
需求很少存在于表面上。它們深深地埋藏在層層假定、誤解和政治手段的下面。
52、與用戶一同工作,以像用戶一樣思考
Work with a User to Think Like a User
要了解系統(tǒng)實(shí)際上將如何被使用,這是最好的方法。開采需求的過程也是開始與用戶群建立和諧的關(guān)系、了解他們對(duì)你正在構(gòu)建的系統(tǒng)的期許和希望的時(shí)候。
53、抽象比細(xì)節(jié)活得更長(zhǎng)久
Abstractions Live Longer than Details
“投資”于抽象,而不是實(shí)現(xiàn)。抽象能在來自不同的實(shí)現(xiàn)和新技術(shù)的變化的“攻擊”之下存活下去。
54、使用項(xiàng)目詞匯表
Use a Project Glossary
如果用戶和開發(fā)者用不同的名稱指稱同一事物,或是更糟,用同一名稱指稱不同事物,這樣的項(xiàng)目很難取得成功。
55、不要在盒子外面思考——要找到盒子
Don't Think Outside the Box - Find the Box
在遇到不可能解決的問題時(shí),問問自己以下問題:
有更容易的方法嗎?
你是在設(shè)法解決真正的問題,還是被外圍的技術(shù)問題轉(zhuǎn)移了注意力?
這件事情為什么是一個(gè)問題?
是什么使它如此難以解決?
它必須以這種方式完成嗎?
它真的必須完成嗎?
很多時(shí)候,當(dāng)你設(shè)法回答這些問題時(shí),你會(huì)有讓自己吃驚的發(fā)現(xiàn)。很多時(shí)候,對(duì)需求的重新詮釋能讓整個(gè)問題全部消失。
你所需要的只是真正的約束、令人誤解的約束、還有區(qū)分它們的智慧。
56、傾聽反復(fù)出現(xiàn)的疑慮——等你準(zhǔn)備好再開始
Listen to Nagging Doubts - Start When You're Ready
你的一生都在積累經(jīng)驗(yàn)與智慧。當(dāng)你面對(duì)一件任務(wù)時(shí),如果你反復(fù)感覺到疑慮,或是體驗(yàn)到某種勉強(qiáng),要注意它。你可能無法準(zhǔn)確地指出問題所在,但給它時(shí)間,你的疑慮很可能就會(huì)結(jié)晶成某種更堅(jiān)實(shí)的東西,某種你可以處理的東西。軟件開發(fā)仍然不是科學(xué)。讓你的直覺為你的表演做出貢獻(xiàn)。
57、對(duì)有些事情“做”勝于“描述”
Some Things Are Better Done Than Described
你應(yīng)該傾向于把需求搜集、設(shè)計(jì)、以及實(shí)現(xiàn)視為同一個(gè)過程——交付高質(zhì)量的系統(tǒng)——的不同方面。不要掉進(jìn)規(guī)范的螺旋,在某個(gè)時(shí)刻,你需要開始編碼。
58、不要做形式方法的奴隸
Don't Be a Slave to Formal Methods
如果你沒有把某項(xiàng)技術(shù)放進(jìn)你的開發(fā)實(shí)踐和能力的語境中,不要盲目地采用它。
59、昂貴的工具不一定能制作出更好的設(shè)計(jì)
Expensive Tools Do Not Produce Better Designs
小心供應(yīng)商的炒作、行業(yè)教條、以及價(jià)格標(biāo)簽的誘惑。在考察工具的產(chǎn)出時(shí),試著不要考慮它值多少錢。
60、圍繞功能、而不是工作職務(wù)進(jìn)行組織
Organize Around Functionality,Not Job Functions
把你的人劃分成小團(tuán)隊(duì),分別負(fù)責(zé)最終系統(tǒng)的特定方面的功能。讓團(tuán)隊(duì)按照個(gè)人的能力,在內(nèi)部自行進(jìn)行組織。
但是,只有在項(xiàng)目擁有負(fù)責(zé)的開發(fā)者、以及強(qiáng)有力的項(xiàng)目管理時(shí),這種途徑才有效。創(chuàng)立一組自行其是的團(tuán)隊(duì)并放任自流,是一種災(zāi)難性的處方。
要記住,團(tuán)隊(duì)是由個(gè)體組成的。讓每個(gè)成員都能以他們自己的方式閃亮。
61、不要使用手工流程
Don't Use Manual Procedures
shell腳本或批處理文件會(huì)一次次地以同一順序執(zhí)行同樣的指令。我們可以自動(dòng)安排備份、夜間構(gòu)建、網(wǎng)站維護(hù)、以及其他任何可以無人照管地完成的事情。讓計(jì)算機(jī)去做重復(fù)、庸常的事情——它會(huì)做得比我們更好。我們有更重要、更困難的事情要做。
62、早測(cè)試,常測(cè)試,自動(dòng)測(cè)試。
Test Early.Test Often.Test Automatically.
與呆在書架上的測(cè)試計(jì)劃相比,每次構(gòu)建時(shí)運(yùn)行的測(cè)試要有效得多。
63、要等到通過全部測(cè)試,編碼才算完成
Coding Ain't Done 'Til All the Tests Run
就是這樣。
64、通過“蓄意破壞”測(cè)試你的測(cè)試
Use Saboteurs to Test Your Testing
在單獨(dú)的軟件副本上故意引人bug,以檢驗(yàn)測(cè)試能夠抓住它們。
65、測(cè)試狀態(tài)覆蓋,而不是代碼覆蓋
Test State Coverage,Not Code Coverage
確定并測(cè)試重要的程序狀態(tài)。只是測(cè)試代碼行是不夠的。即時(shí)具有良好的代碼覆蓋,你用于測(cè)試的數(shù)據(jù)仍然會(huì)有巨大的影響,而且,更為重要的是,你遍歷代碼的次序的影響可能是最大的。
66、一個(gè)bug只抓一次
Find Bugs Once
一旦測(cè)試員找到一個(gè)bug,這應(yīng)該是測(cè)試員最后一次找到它。此后自動(dòng)測(cè)試應(yīng)該對(duì)其進(jìn)行檢查。
67、把英語當(dāng)作又一種編程語言
Treat English as Just Another Programming Language
像你編寫代碼一樣編寫文檔:遵守DRY原則、使用元數(shù)據(jù)、MVC、自動(dòng)生成,等等。
68、把文檔建在里面,不要拴在外面
Build Documentation In,Don't Bolt It On
與代碼分離的文檔不太可能被修正和更新。使用像JavaDoc和NDoc這樣的工具,我們可以根據(jù)源碼生成API級(jí)的文檔。
文檔和代碼是同一底層模型的不同視圖,但視圖是唯一應(yīng)該不同的東西。
69、溫和地超出用戶的期望
Gently Exceed Your Users' Expectations
要設(shè)法讓你的用戶驚訝。請(qǐng)注意,不是驚嚇?biāo)麄儯且屗麄兏吲d。要理解用戶的期望,然后給他們的東西要多那么一點(diǎn)。給系統(tǒng)增加某種面向用戶的特性所需的一點(diǎn)額外努力將一次又一次在商譽(yù)上帶來回報(bào)。
70、在你的作品上簽名
Sign Your Work
我們想要看到對(duì)所有權(quán)的自豪。“這是我編寫的,我對(duì)自己的工作負(fù)責(zé)。”你的簽名應(yīng)該被視為質(zhì)量的保證。當(dāng)人們?cè)谝欢未a上看到你的名字時(shí),應(yīng)該期望它是可靠的、用心編寫的、測(cè)試過的和有文檔的,一個(gè)真正的專業(yè)作品,由真正的專業(yè)人員編寫。
一個(gè)注重實(shí)效的程序員。