自上而下設計,由下而上實現

2022-05-04 12:12:13 字數 2441 閱讀 5514

多年前的乙個 ibm 的老鳥曾經教過我乙個 5 分鐘上手的思維習慣,當我聽到以後,醍醐灌頂,驚人天人,一改日常的編碼風格。到現在,它還持續保持在我的日常的編碼習慣當中。

我不知道應該怎麼稱呼這種思維習慣的名字,top-down,自頂而下,或者分治?不管怎麼樣,它的核心是非常清晰的:編碼的時候只思考同乙個思維層次的邏輯,在這層完成之後再思考下一層

它基於這麼乙個事實:我們每個人智力是有限的,同乙個時間只能思考有限內容的東西,我們都不是天才。由於這個事實的存在,所以程式 bug 就會存在(廢話)。因此,思考問題的時候(編碼)不要跨抽象層級思考,在我們有限的智力裡面現保證這個層級的邏輯正確,再思考下乙個。什麼叫跨抽象層級思考,什麼叫同乙個抽象層級的思考。我們通過乙個例子來看看,假設現在我要編寫程式打車去上班。

首先穿衣服,然後洗臉刷牙上廁所,然後下樓打車。

這句話就算是乙個三歲的人都能說出來。上面的描述是在同乙個思維層次,把「打車上班」這個事情分成了幾個符合順序和操作邏輯的模組和動作,我的大腦能夠承載這些邏輯,這一套邏輯下來就能夠把這件事情完成。於是我把它寫下來:

def goworkbycar () 

dressup()

wash()

godownstairs()

gobycar() }

這個抽象層次的東西已經完成了,我看這個函式就知道這個操作的順序和邏輯是什麼,甚至還不用注釋。我們有四個函式都是沒有完成的,它們的具體實現就是下乙個抽象層次的東西。我們現在下到下一層,看看dressup。現在我的注意力已經不在打車上班這件事情上了,這一層的邏輯已經完成了。我的注意力在怎麼穿衣服這件事情上:

從櫃子裡把衣服拿出來,先穿上半身,再穿下半身。

符合正常的操作,不錯:

def dressup ()

clothes = takeclothesfromwardrobe()

dress(clothes.up)

dress(clothes.down)

我們看看洗漱怎麼做:

上廁所,刷牙,洗臉

def wash () 

urine()

brushteeth()

washface()

下樓呢?

我要先出門,然後鎖門,然後坐電梯。

def godownstairs () 

opendoorandout()

lockthedoor()

takethelift()

打車呢?

用手機打車,然後坐車走人

def gobycar () 

car = callacarbyphone()

takethecar(car)

...然後再用這種方式實現像brushteethwashface具體的實現,想想它們需要什麼操作。

你會發現我們不停地在填函式,函式裡面又不停地出現新的函式需要我們去完成。每個函式體裡面的操作都和這個函式所要完成的目的相關,在乙個函式裡面,我們只關心這個函式需要完成的目標所需要操作。例如「打車上班」這個任務所依託的 goworkbycar,我們在這裡並不關心怎麼刷牙,因為它是下一層的東西,我們只關注完成「打車上班」這個目標需要哪幾步。如果我們刷牙、開門這些操作都放在這個函式裡面,那麼一開始就會陷入無限的細節當中而失去了主要目的的關注,而且大腦也無法承載如此複雜多端的細節,處理不好就很容易出現 bug

而這種思維方式可以讓我們不停地把乙個大的任務在同乙個層級做分解,保證這一層的步驟和邏輯正確以後,然後再下一層分解,最後其實是乙個樹狀的結構,樹的葉子結點才是具體的**演算法實現。在編碼的時候,我只用我有限的腦力關注當前層級的任務,不關注上一層也不關注下一層的細節。

這樣的**寫出來不僅 bug 少,邏輯清晰而且還很輕鬆,因為你每一層思考的東西其實都很簡單,不知不覺就把**寫完了。為什麼很多人覺得程式設計很難,因為你接到乙個「打車上班」的任務以後就開始腦子裡面就填滿了刷牙打車穿衣服這種不成邏輯和順序的任務,並且都把它寫到乙個函式裡面去。

接到任務以後你可以像上面一樣用人類語言描述一下如果你要解決這個任務,你需要什麼步驟。這些步驟才是這一層任務的關注點。例如跟女朋友看電影:你要先看看有什麼好電影,然後再約女朋友,再買票。

(update:有朋友說這裡第一步應該先找女朋友,同意!!必須同意!全身同意!每個細胞都同意!)

當你寫一行**的時候可以經常看看你的函式名,你這行**和你的函式名所代表任務的是不是同乙個邏輯層次的東西,不是的話,把它分出去。

flex中實現marquee效果(由下而上滾動)

最近做乙個小專案需要用到這個效果,今天專案完成,將這個效果拿出與大家分享。原理其實就是使用乙個text 或者textarea 控制項,然後新增乙個move效果,使text控制項向上移動。其中關鍵的一點是 在creationcomplete事件中獲取控制項高度,否則會出現高度誤差偏大。源 如下 公告欄...

溫習下設計模式

1 工廠模式 抽象基類 類中定義抽象一些方法,用以在子類中實現 繼承自抽象基類的子類,實現基類中的抽象方法 工廠類,來例項化所有的子類 工廠類是必須的,讓程式根據使用者的輸入自動例項化相應的類。2 單例模式 只有乙個例項。自行例項化,並且向整個系統提供這個例項。要點 某個類只能有乙個例項 必須自行建...

protus下設計數控電流源簡單總結

乙個朋友委託我搞乙個本科生畢業設計,在protus下設計數控電流源,protus好久沒有摸了,這兩天小試了下還是大部分都記得,在此設計的數控電流源精度一般,總結如下 1.設計程式的時候發現flag標誌位太多,感覺有點混亂,原因是只是大概的流程圖設計好了,沒有精確到每個部分,也許是時間上的原因 2.主...