編程:思考或打字,思考和打字
”如果你思慮不周,你也許會(huì)認(rèn)為編程只是一行一行把代碼語(yǔ)句敲進(jìn)電腦里?!啊猈ard Cunningham 在《程序員修煉之道:從小工到專家》中的序言提到。
軟件開(kāi)發(fā)包含很多需要深入思考的內(nèi)容,諸如設(shè)計(jì)、解決問(wèn)題、找出最佳算法,學(xué)習(xí)新語(yǔ)言,重構(gòu)混亂的代碼,使其變得整潔而優(yōu)雅等等。
當(dāng)你嘗試去做一件你從沒(méi)做甚至從來(lái)沒(méi)有人做過(guò)的事;或者你以前做過(guò),但毫無(wú)疑問(wèn)不想再犯類似的錯(cuò)誤,而需要去思考一個(gè)更好的方法;或者你嘗試去理解其他人寫(xiě)的代碼以便修改;或者你正在查找一個(gè)討厭的BUG。所有這些都會(huì)占用大量的時(shí)間,但最終并不會(huì)產(chǎn)生很多代碼。
同時(shí)軟件開(kāi)發(fā)中也有許多需要大量打字而不需要過(guò)多思考的工作。比如當(dāng)你很清楚需要做什么并且如何做時(shí),但是在工作完成之前,你需要編寫(xiě)大量的代碼,因?yàn)槟阒白鲞^(guò)類似的東西,所以僅僅需要再做一遍,用另一種腳本,適應(yīng)另一種屏幕,另一種報(bào)告,另一種除了思考之外的所有東西;或者工作中大部分需要思考的工作已經(jīng)有人為你做好了,他給你提供了程序線框圖,精確向你描述這個(gè)程序看起來(lái)的樣子,給人的感覺(jué)以及數(shù)據(jù)的流動(dòng),或者提供了詳細(xì)的API說(shuō)明,所以,你要做的事僅僅是把這些思考的結(jié)果敲進(jìn)屏幕同時(shí)確保不要犯太多錯(cuò)誤。
調(diào)試程序是思考型工作(Debugging is thinking)。而修復(fù)BUG、使其通過(guò)測(cè)試、發(fā)布主要是輸入型工作。早期的設(shè)計(jì)和開(kāi)發(fā),決定使用的技術(shù)并設(shè)計(jì)框架,是艱難的思考型工作,而基于此開(kāi)發(fā)三個(gè)、四個(gè)或100個(gè)的適應(yīng)屏幕或報(bào)告的程序是輸入型工作。用戶體驗(yàn)和原型設(shè)計(jì)是思考型的工作,而將其實(shí)現(xiàn)(包括CRUD、適應(yīng)不同屏幕的配置)卻是輸入型工作。找到一個(gè)酷的移動(dòng)應(yīng)用點(diǎn)子是思考型工作,而實(shí)現(xiàn)它卻是輸入型工作。解決一般的業(yè)務(wù)問(wèn)題需要大量的編碼,而通過(guò)軟件優(yōu)化業(yè)務(wù)流程去需要大量艱難的思考。
所以,思考型工作的人和輸入型工作的人做著不同的工作,并且需要用不同的方式管理。
有時(shí)候編程就是在打字輸入
”我們首先是打字員,然后才是程序員?!啊狫eff Atwood, Programming Horror許多業(yè)務(wù)程序本質(zhì)上是很膚淺的。大量的數(shù)據(jù)庫(kù)表和文件充斥著大量的元素和數(shù)據(jù),大量的增刪改查頁(yè)面、報(bào)表相互之間有許多的相似之處;大量的集成工作把不同屬性的不同點(diǎn)映射統(tǒng)一,從而使其滿足約束并在操作上獨(dú)立對(duì)待。功能需求上冗長(zhǎng)的列表,通過(guò)一大堆的問(wèn)題確保每個(gè)人都理解需求,許多細(xì)節(jié)描述用來(lái)備忘和追蹤。銀行、保險(xiǎn)、政府、會(huì)記、財(cái)務(wù)報(bào)表和賬單、庫(kù)存管理和ERP系統(tǒng)、CRM系統(tǒng),企業(yè)內(nèi)部應(yīng)用、簿記系統(tǒng)、記錄系統(tǒng)等等都是如此。許多在線門戶和商店也一樣。一些維護(hù)型工作,如平臺(tái)升級(jí)、系統(tǒng)集成和移植、稅收變化等也是如此。
你是在建造一幢房子、一座橋、一個(gè)百貨商場(chǎng),或是改造其中之一。大項(xiàng)目經(jīng)常不斷滋生各種問(wèn)題,通常要花費(fèi)大量時(shí)間去解決。很多輸入型工作需要做,但是其中有一部分之前已經(jīng)做過(guò)很多次了,那些工作涉及類似的問(wèn)題,所以你可以應(yīng)用熟悉的模式、被證明可靠的工具和工作方法。
“我昨天看了你電腦程序的源代碼,它看起來(lái)很簡(jiǎn)單;只是打了很多字,其中一半還拼寫(xiě)錯(cuò)誤。還有,別再讓我抱怨你那過(guò)渡使用的冒號(hào)了?!?—— 《The Pointy Haired Boss sees some actual code》
一旦設(shè)計(jì)確定,絕大部分工作都被充分理解并考慮了所有的細(xì)節(jié),剩下的就是管理和協(xié)調(diào)程序員去把這是代碼敲出來(lái)。這是一種經(jīng)典的項(xiàng)目管理流程:預(yù)算、計(jì)劃、跟蹤成本和調(diào)整、管理計(jì)劃。這是關(guān)于邏輯、規(guī)模、一致性和效率的問(wèn)題,確保工作在正確的軌道上運(yùn)行。
思考!思考!思考!
其他的問(wèn)題,比如設(shè)計(jì)一個(gè)游戲引擎、交易算法、物流或在線風(fēng)險(xiǎn)管理系統(tǒng)、優(yōu)化一個(gè)實(shí)時(shí)控制系統(tǒng),這些工作需要的思考都大于輸入編碼。這些系統(tǒng)有著高標(biāo)準(zhǔn)、非技術(shù)性需求(可擴(kuò)展性、實(shí)時(shí)性能、可靠性、數(shù)據(jù)完整性和正確性)和復(fù)雜的邏輯,但是他們集中在解決一系列緊密結(jié)合的問(wèn)題。只有很少一部分聰明的程序員可以思考那些問(wèn)題并實(shí)現(xiàn)。當(dāng)然,編碼工作仍然需要去做,特別是“外圍”部分,框架、管道、布線方式等,但是核心的部分通常只有非常少量的代碼,尤其是在拋棄失敗的試驗(yàn)和原型之后。
這就是軟件的奧秘所在,有版權(quán)或?qū)@乃惴ê驮O(shè)計(jì)的洞察力是一個(gè)成功系統(tǒng)的核心。這種工作需要花費(fèi)大量的時(shí)間去研究、需要無(wú)數(shù)次的設(shè)計(jì)原型、需要解決問(wèn)題的能力,要么需要過(guò)硬的技術(shù),要么需要深刻的領(lǐng)域知識(shí),又或者要求二者兼?zhèn)洹?br />
編碼輸入和思考是不同種類的工作
工作的性質(zhì)以編碼為主,還是以思考為主,影響著你的團(tuán)隊(duì)需要的人員數(shù)量和類型。這會(huì)改變?nèi)藗冎g如何合作,以及你如何取管理團(tuán)隊(duì)。編碼可以被外包,但思考不行。你需要認(rèn)識(shí)到哪些問(wèn)題可以通過(guò)編碼解決,而哪些不行,以及什么時(shí)候思考型工作轉(zhuǎn)變?yōu)榫幋a輸入型工作。
思考型工作可以也應(yīng)該交給一個(gè)小而精的專家團(tuán)隊(duì),或者干脆托付給一個(gè)天才。在思考設(shè)計(jì)或思考復(fù)雜問(wèn)題、反復(fù)試驗(yàn)的階段,你不需要太多的人。做這種工作的人需要完全沉浸其中,在這段時(shí)間里,他們會(huì)開(kāi)展探索性研究,也可能會(huì)犯錯(cuò)誤,他們會(huì)學(xué)習(xí),在遇到困難時(shí),也許僅僅會(huì)盯著屏幕發(fā)呆(其實(shí)是在思考啦^_^)。
這個(gè)階段極其重要,因?yàn)樵诖怂傅腻e(cuò)誤通常都是致命的(終結(jié)項(xiàng)目或職業(yè)生涯級(jí)別的錯(cuò)誤)。比如選擇了錯(cuò)誤的技術(shù)平臺(tái);假設(shè)了錯(cuò)誤的實(shí)時(shí)系統(tǒng)的可容忍延遲;花費(fèi)大量的時(shí)間去尋找(或者根本找不到)高可靠性的方案;挑選了錯(cuò)誤的人員或者嘗試去解決錯(cuò)誤的問(wèn)題;使項(xiàng)目失去了節(jié)奏。
管理此類工作需要尋找最優(yōu)秀的人才,確保他們有正確的信息和工具,讓他們專注,同時(shí)要觀察外界的風(fēng)險(xiǎn),以確保他們不被打擾。
思考型的工作是不可預(yù)知的。不存在“復(fù)制粘貼”的方法,因?yàn)槟愀静恢缽哪摹皬?fù)制和粘貼”。你不可能估計(jì)此類工作,因?yàn)槟愀静恢烙卸嗌偈聞?wù)是你所不知道的。但是你可以設(shè)置一個(gè)時(shí)間限制,嘗試尋找規(guī)定時(shí)間內(nèi)的最佳方案。
編碼輸入型工作是可預(yù)知的。你可以同時(shí)也不得不去估計(jì)這類工作。訣竅在于把所有需要編碼的工作的列出來(lái),并為工作中所有可能遇到的錯(cuò)誤和變化做出估計(jì)。它們通常會(huì)隨著項(xiàng)目的進(jìn)行而快速增加,諸如程序員的粗心大意、錯(cuò)誤理解了需求、遺漏了測(cè)試、簡(jiǎn)單的“復(fù)制粘貼”,這些都會(huì)導(dǎo)致現(xiàn)在和將來(lái)的成本增加。
編碼輸入是一種工人式的工作。雖然一些高級(jí)開(kāi)發(fā)者在他們厭煩前可以媲美一個(gè)大團(tuán)隊(duì)的工作,但是你不需要專家,那些理解所用語(yǔ)言和工具的基本原則、細(xì)心并且原因服從指示、耐心的人都可以勝任此類工作。管理一群“打字員”需要不同的方式和技巧:你需要嘗試變成一個(gè)政客、一個(gè)外交家、一個(gè)后勤人員、一個(gè)標(biāo)準(zhǔn)制定者、一個(gè)管理員、一個(gè)經(jīng)濟(jì)學(xué)家的角色。你是在管理項(xiàng)目和人員的風(fēng)險(xiǎn),而非技術(shù)。
一段時(shí)間后,一旦大部分“我們不確定我們需要且如何去做”的艱難工作被解決了、一旦未知的事務(wù)被逐漸掌握,思考型工作就轉(zhuǎn)變?yōu)榱溯斎胄凸ぷ鳎@時(shí)候就需要去填補(bǔ)細(xì)節(jié)并使流程跑通。
當(dāng)系統(tǒng)的用戶增加,不得不去處理更多的接口、地點(diǎn)、本地化、電子郵件、摘要、支持和承諾時(shí),你就需要開(kāi)展更多的輸入型工作。系統(tǒng)保持增長(zhǎng),但是大部分的問(wèn)題都是熟悉且可解決的。有大量的代碼可供查找、學(xué)習(xí)和復(fù)制。你需要的是能夠從中挑選所需和打字快的程序員。
思考和編碼/輸入
思考和編碼都是軟件開(kāi)發(fā)的重要組成部分。
在《編程不僅僅是打字》一文中。Brendan Enrick解釋了結(jié)對(duì)編程有用的原因:這可以讓兩個(gè)程序員同時(shí)各自專注在思考和編碼兩個(gè)方面。
”兩個(gè)人都在思考,但思考的內(nèi)容不同。一個(gè)開(kāi)發(fā)者擁有鍵盤,并且沉浸其中(這種開(kāi)發(fā)者需要一定的打字速度),他依照當(dāng)前的代碼邏輯進(jìn)行編碼而不是整個(gè)應(yīng)用的結(jié)構(gòu)。一段時(shí)間后,他編碼的速度就會(huì)提高。
在結(jié)對(duì)編程中不實(shí)際編碼的人把所有的時(shí)間都專注在思考上。他的腦子中具有編碼者工作的清晰流程,但并不關(guān)心實(shí)際編程語(yǔ)言的語(yǔ)法,實(shí)際的編碼者才需要關(guān)心語(yǔ)法。這種在編碼者身后坐著的人,更像是一位向?qū)?,他必須確保工作進(jìn)展在正確的道路上,并使用最有效的方式去實(shí)現(xiàn)它。“
成為一位優(yōu)秀的開(kāi)發(fā)者比單純的編碼輸入更出色,而成為一位得力的編碼輸入者也比簡(jiǎn)單的敲擊鍵盤更優(yōu)秀。這意味你必須有很好的基礎(chǔ):掌握足夠的編程語(yǔ)言特性,知道用什么工具以及如何使用,要會(huì)讀代碼,當(dāng)然也要知道如何寫(xiě)代碼(同時(shí)要寫(xiě)得快);學(xué)會(huì)控制你的工具、知道使用哪種編碼更快,這樣你就更加靈活,這些都是接替一個(gè)開(kāi)發(fā)者所必須的。最后,不要低估編碼輸入的重要性,也不要讓那些本該是輸入型的工作變成思考型的工作。
編程:思考或打字,思考和打字