設計邏輯和程式碼邏輯
本文是對這兩個文件的總結:
in nek:狀態機退出方法 zhuanlan.zhihu.com in nek:不為天下先2 zhuanlan.zhihu.com目的是基於這兩個文件的一些場景,進一步討論一下什麼樣的邏輯屬於設計文件,什麼樣的邏輯屬於程式碼邏輯。
我以前就寫過一些討論,談到“程式碼不能代替設計文件”,或者“這樣的邏輯不屬於設計文件,它應該屬於編碼”。但我沒有更好的邏輯來更直接地說明這兩個結論的原因。但有了這兩個推演,我想我有更好的邏輯來描述這兩個問題了。
在上面這個狀態機退出方法的討論中,我給出了三個獨立的邏輯:
- 狀態機
- 把刺激通道化,排隊化(比如通過鎖或者排隊設計)
- 狀態退出過程保護
我認為,這些東西,就是“設計邏輯”。比如你定義系統有5個狀態,在每個情形下做什麼,然後看有沒有狀態的處理是不對的。
這種東西靠看程式碼是看不出來的(除非你對著程式碼重新畫一次),在程式碼升級、修改的時候不看著這個狀態機,你程式碼寫得對不對,你也是不能肯定的,它非常燒腦。
這種邏輯就屬於設計文件。
反之,如果你寫,在abc_op1()的時候,先上A鎖,然後修改x變數,然後給T發一個訊號,然後修改狀態到sx2,然後解A鎖。這個就不屬於設計文件的邏輯了,因為這種東西和程式碼的邏輯是重疊的,在設計文件中寫好了,搬到程式碼去都一樣,拿個Word,Latex之類的東西寫出來,還不如直接寫到程式碼中呢,你寫成文件,還需要同步,這完全吃飽了撐的,這就屬於浪費時間了。
同樣的,你寫對刺激排隊的策略,你說你把什麼行為看做是對狀態機的刺激,他們有哪些執行緒(包括中斷等)可以把刺激送進來,你用什麼鎖來保證進去以後相關的執行過程可以排隊。這個邏輯就屬於文件。但你討論每個刺激函式怎麼寫,這個就不是設計了。這是編碼,就算不寫在.c,.go中,它們依然是程式碼。
就算你進行抽象,比如abc_op[1..3]()的行為是這樣這樣……,abc_op[4..5]()的行為是那樣那樣。這仍屬於編碼。因為他們並不是獨立於程式碼的建模。關鍵是這些邏輯寫在文件中,沒有一個明確的邏輯鏈可以驗證它對不對。你既沒有說這些opX是你的操作的全集,也沒有說他們屬於哪個執行緒,也沒有和狀態機的維護關聯在一起。這裡就沒有獨立的邏輯鏈可以建。這個邏輯獨立到文件中的意義在哪裡?它的邏輯對還是不對?不看程式碼都不會知道。既然它不是獨立邏輯,不看程式碼都不知道對不對,它寫出來,作為程式碼之外的獨立推演,有什麼用?
正如我們在《不為天下先2》中提到的,架構(高層)設計的目的不是下層設計的預演,它工作在另一層邏輯上,它是預期下一層設計是要加入新的邏輯的,但它為下一層設計設定另一層邏輯的限制,保證下一層設計可以聚焦,我們推演完了狀態機。下一層只要考慮我現在是從什麼跳到什麼上,不需要再擔心這樣跳法會不會出什麼問題。推演完鎖的原則,下一層設計只需要考慮設定的鎖的原則,什麼情況用什麼鎖,就可以保證不會發生死鎖,或者不會在某個流程中少用了鎖。每個邏輯屬於什麼層次的設計,其實大部分時候是有明顯的分界的,它們通常通過邏輯鏈的關聯度進行分層隔離,比如某個邏輯要素不在和任何人相關,它就會被獨立出來,它就會屬於那一層,這樣程式碼才有立體一說。否則就又都壓平了。