
導(dǎo)語
- 下面的內(nèi)容是在學(xué)習(xí)編程思想的過程中產(chǎn)生的感想
- “編程”其實和做很多事情一樣揽涮,掌握了步驟和方法后据某,會變得不那么難
- 略去了具體的編程內(nèi)容和案例录择,只保留了概念(不多桦卒,只有幾個)
- 感覺邏輯挺嚴謹?shù)牧⒚溃M麤]有漏洞
- 下一步目標是不斷回顧、運用和驗證這些思考方灾。
一種開發(fā)方法
- 封裝(Encapsulation)
- 泛化(Generalization)
- 接口設(shè)計(Interface design)
- 重構(gòu)(Refactoring)
這是一種開發(fā)方法建蹄,它有缺點碌更,但如果在開始編程時不清楚如何將程序分成合適的函數(shù)時(問題分解),這個方法會有效洞慎。
封裝:把一段代碼用函數(shù)包裹起來痛单,成為封裝。
泛化:給函數(shù)添加參數(shù)的過程劲腿。也就是把前面封裝的函數(shù)內(nèi)的常數(shù)給參數(shù)化旭绒。
- 接口設(shè)計:設(shè)置參數(shù)、返回值焦人,注釋函數(shù)作用挥吵。這個步驟算是包含在泛化、重構(gòu)之內(nèi)花椭,是一個很具體的方法忽匈。
重構(gòu):重新組織程序,以改善接口矿辽,提高代碼復(fù)用丹允。
這個開發(fā)方法的具體步驟是”封裝-泛化“循環(huán):
- 最開始用一些常數(shù)寫一些小程序,而不需要定義函數(shù)
- 一旦程序運行成功嗦锐,識別出其中一段完整的部分嫌松,把它封裝成一個函數(shù)
- 泛化這個函數(shù),添加合適的形式參數(shù)
- 循環(huán)上面3個步驟奕污,直到得到一組可行的函數(shù)
- 尋找可以使用重構(gòu)來改善程序的機會萎羔。例如,發(fā)現(xiàn)程序中幾處相似的地方碳默,可以考慮將他們抽取出來做成一個通用的函數(shù)
問題求解:“封裝-泛化”循環(huán)的原因贾陷、背后的原理
問題求解(Problem Solving):
界定問題
創(chuàng)造性地思考解決方案
清晰準確地表達解決方案的能力
(formulate problems)
(think creatively about solutions)
(express a solution clearly and accurately)
這樣寫出來其實很容易誤導(dǎo)人,會讓人覺得這三個步驟都是小步驟嘱根,很容易完成髓废。但如果真的帶著這樣的認識來處理問題的話,很可能是碰一鼻子灰该抒。而真實的情況是:每一步都有單獨的值得注意的方法慌洪,并且這三個大步驟也是緊密聯(lián)系著的。
上一節(jié)提到的編程概念”封裝-泛化“的循環(huán)重復(fù)凑保,這一過程就是在整個”問題求解“中產(chǎn)生的冈爹。也就是說”問題求解“是更抽象的思考層面,而”封裝-泛化“的循環(huán)重復(fù)就是具象化的操作層面欧引。
可是………………
但是………………
到這里我發(fā)現(xiàn)了問題频伤。不得不打臉承認我犯了一個錯誤:強行歸因,強行找聯(lián)系芝此。
“問題求解”的步驟和“封裝-泛化-重構(gòu)”的步驟其實并不是一一對應(yīng)了憋肖∫蛲矗可是我急于找出“成果”,急于獲得“正面反饋”的心態(tài)讓我在看到一些貌似是關(guān)聯(lián)的現(xiàn)象中岸更,在還沒有證實之前鸵膏,不假思索地就確認了。
這雖然是題外話怎炊,跟筆記的主題無關(guān)较性,但又確實很值得記錄下來,因為這確確實實是我們經(jīng)常犯的邏輯錯誤结胀。我們的”系統(tǒng)一”(情感、直覺大腦)和“系統(tǒng)二”(理性责循、邏輯大腦)交互時產(chǎn)生的BUG糟港。(詳情參考《思考,快與慢》《超越智商》等書籍)
回到發(fā)現(xiàn)的這個錯誤中來院仿。這兩種循環(huán)很可能并不是一一對應(yīng)的秸抚。
先說界定問題
我首先想到的就是《金字塔原理》一書中介紹的界定問題的方法。不過現(xiàn)在想來歹垫,有可能是作者芭芭拉·明托在了解了科學(xué)家們的思考方法后借鑒領(lǐng)悟的也說不定……誰知道呢剥汤,因為作者在介紹界定問題的方法“連續(xù)分析”時,在“連續(xù)分析”這個名稱后加了括號備注:
連續(xù)分析(統(tǒng)計學(xué)上稱為序列分析)
其實現(xiàn)在想來排惨,整個《金字塔原理》都是在學(xué)習(xí)科學(xué)家們的思考方法——理性吭敢、邏輯。書里面在很多地方也提及了相關(guān)的東西暮芭,比如附錄1等鹿驼。
關(guān)于界定問題,《金字塔原理》說了很多辕宏,花了很多篇幅畜晰,還加了附錄。但是之所以花這么多篇幅瑞筐,除了有湊字數(shù)的嫌疑之外凄鼻,還有就是大量的介紹了各種具體的情況,都說具體問題具體分析聚假,從這個角度看块蚌,作者還是很嚴謹負責的……
那么界定問題的核心方法一張圖就能展示完:
首先,面對一個問題的時候魔策,先看看這個問題是具體的眼睛能看見的東西匈子,還是看不見的通過想象的東西。
肉眼能看見的:觀察這個東西闯袒,抓住每一個細節(jié)虎敦,然后分解這個東西游岳,分解成自己熟悉的模塊(chunks)。
看不見的:思考問題的上下文(context)是什么其徙,也就是背景胚迫。
然后,明確我想要達到的目標(R2)是什么唾那,再審視現(xiàn)狀(R1)访锻,R2與R1的差距就是現(xiàn)在的問題、困擾闹获。這個步驟就是俗話說的“不忘初心”……仔細想想平時我們很容易迷失方向期犬,迷茫,不知所措避诽,究其原因很可能就是把“初心”(最初的目標)給忘了龟虎。
這里有一個需要注意的細節(jié)。因為R2沙庐、R1之間的差距鲤妥,我們發(fā)現(xiàn)了問題,但這個問題能迅速找到對應(yīng)的解決方案嗎拱雏?這就是關(guān)鍵棉安。換句話說,解決方案是否已經(jīng)存在铸抑?如果沒有現(xiàn)成的解決方案贡耽,則要花時間去尋找。
假定解決方案已存在羡滑,或者說菇爪,在我們不斷界定問題的過程中(R1到R2、R3到R4柒昏、R5到R6)凳宙,經(jīng)歷了問題、困惑被不斷分解的過程后职祷,在最后一步找到了解決方案氏涩,然后就逆推回去。這也是一個逆反演繹推理的過程:從結(jié)論逆推回到-小前提-大前提有梆。
再說思考解決方案
到了這一步是尖,我突然發(fā)現(xiàn):
- 其實在“界定問題”這個過程里,“思考解決方案”是嵌在其中的泥耀。也就是說饺汹,這個過程產(chǎn)生了一個“問題-解決方案”的重復(fù)循環(huán)。
這和“封裝-泛化”循環(huán)是一樣的痰催!這驗證了我之前“腦袋一熱”產(chǎn)生的聯(lián)想:
前面說到”封裝-泛化“的循環(huán)重復(fù)兜辞,這一過程就是在整個”問題求解“中產(chǎn)生的迎瞧。也就是說”問題求解“是更抽象的思考層面,而”封裝-泛化“的循環(huán)重復(fù)就是具象化的操作層面逸吵。
當然還是有細節(jié)上的差異的凶硅,因為包含的信息量不一樣,”封裝-泛化“循環(huán)更偏向于”解決方案“這一邊扫皱。換句話說足绅,”問題-解決方案“循環(huán)包含了”封裝-泛化“循環(huán)。不過他們很接近韩脑,從整體上可以看作是一樣的氢妈。
通過展開思考分析,這里我又推翻了之前自己”冷靜下來”后的否定段多,重新驗證了之前的假設(shè)允懂,再次打臉……不過,這個過程也實實在在地是對“假設(shè)-驗證”方法的一次運用衩匣。詳情參考:科學(xué)實驗方法
關(guān)于“思考解決方案”這一個步驟還有3個需要討論的點:
- 相關(guān)領(lǐng)域內(nèi)概念的擴充
- 不斷地重復(fù)練習(xí)
- 記錄下來,形成書面文檔粥航,以便復(fù)用
在界定好問題后琅捏,開始找解決方案,那解決方案又怎么找呢递雀?這就需要我們掌握足夠多的概念柄延,以及由這些概念組成的套路。學(xué)習(xí)的意義缀程、看書的意義搜吧、請教老師的意義也就在此——為了掌握概念和套路。
但是杨凑,只是知道了“概念”和“套路”還不夠滤奈,那就只能當解說員,都知道但就是做不到(當然撩满,以解說作為職業(yè)賺錢就是另一種性質(zhì)了)蜒程。而知道做到的關(guān)鍵點就在于:不斷地重復(fù)練習(xí)。這也是一個很樸素的道理伺帘,很多人都知道昭躺,但毫不意外的就是做不到。原因很簡單伪嫁,這么做太枯燥领炫,且大多數(shù)都沒有即時反饋,也就是不能馬上看到成果张咳。這種現(xiàn)實是我們的”系統(tǒng)一”(情感帝洪、直覺大腦)所不能忍受的似舵!再加上現(xiàn)在這個聲色犬馬的時代,有太多分心的東西……如果想要知道做到碟狞,除了下決心遠離”娛樂“的東西外啄枕,還有就是持續(xù)跟進自己的練習(xí),這樣能盡可能的獲得即時反饋族沃,滿足”系統(tǒng)一”(情感频祝、直覺大腦)的需求。
“持續(xù)跟進”的一個重要方法就是“記錄”脆淹〕?眨看書要做筆記,練習(xí)后要復(fù)盤都是這樣盖溺。最好是能把這些都形成書面的文檔漓糙,以便復(fù)用。由此也需要我們勤于“寫寫寫”烘嘱。畢竟這是一種人類文明突進以來最重要的傳承方式之一昆禽,因為確實很有用……
最后說說表達解決方案的能力
這一點我們馬上就會想到上面討論的“記錄”。確實這是很重要的一種表達方式蝇庭,但還有更重要的醉鳖,隱藏在“表達”背后的東西:重構(gòu)(refactoring)。因為有了“重構(gòu)”哮内,解決方案可以得到更精煉盗棵、準確地表達。
“重構(gòu)”的具體含義是:在不斷地進行“封裝-泛化”的循環(huán)后北发,我們從產(chǎn)生的眾多解決方案里歸納出重復(fù)出現(xiàn)的纹因,提取出這些通用的、重復(fù)的點琳拨,再次封裝他們瞭恰,使解決方案更有效率,更簡潔狱庇。這個方法其實和《金字塔原理》中表達的邏輯是一樣的:都是使用歸納法找出性質(zhì)一樣的東西作為一類寄疏,這樣提煉出幾個要點,表達時就說這幾個要點僵井,有需要時再詳細展開其中一個要點即可(在“重構(gòu)”中就是再次定制這個通用點陕截,以滿足特定需求)。
函數(shù)
這篇筆記本來是為了記錄一些概念的批什,沒想到在記錄之中突然冒出很多感想农曲。所以把函數(shù)這個本來在前面的筆記放在了最后。
本來是想偷懶把函數(shù)的筆記略過的,因為覺得函數(shù)的筆記沒多少乳规,挺簡單的形葬。但仔細想了一下,發(fā)現(xiàn)有兩個函數(shù)的概念很重要暮的,殊不知開發(fā)中很多很多方面都要涉及到笙以,并且在Python里,很多很方便的功能都是已經(jīng)封裝好的函數(shù)冻辩。
- 實參和形參:
要理解函數(shù)的運用猖腕,就先得理解兩個概念:實際參數(shù)和形式參數(shù)(argument and parameter),以及它們之間的關(guān)系恨闪。
實參是在函數(shù)里真正要使用的那個“值”倘感,而形參是在函數(shù)還沒被調(diào)用時,為了完整呈現(xiàn)函數(shù)咙咽,而設(shè)置的”樣例“老玛。所以,在調(diào)用函數(shù)并輸入了實際參數(shù)后钧敞,這個實際參數(shù)會相應(yīng)地取代形式參數(shù)所在的地方蜡豹,然后把自己代入這個位置。