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