再談什麼是高層設計
這次談架構設計的一個外延。這裡用高層設計這種叫法,既可以是架構設計,也可以是系統設計,乃至大一點模組的概要設計。無論是那種,下面的討論都是成立的。
想起要討論這個話題,是因為最近和一些朋友、同事討論起新的構架設計趨勢,他們談到一些構架工具直接轉換程式碼的努力,基於模型進行設計的嘗試(比如scade suit這樣的方案),還有通過形式化驗證來保證架構上的演算法定義可以被徹底地觀測等。
我個人完全不看好這個方向,我不否認在特定的場合它們可以發揮一定的作用。但他們有一個依賴在現實中是無法得到滿足的。這依賴就是,認為高層設計是可以Specific的。但高層設計恰恰是不Specific的設計。
怎麼說呢?比如說,你跟別人說,“給我來杯咖啡”。這句話(需求)是不Specific的,因為你沒有說:
- 什麼咖啡?
- 多大叫“一杯”
- 什麼才算給你“來一杯”?我幫你喝了,然後把賬單落你頭上算不上“給你來一杯”?
等等。
實際上,沒有任何需求是可以Specific的。所以,我們說的Specific,是這個選擇在我們的需求語氣範圍內,我們就認為它是Specific的。比如我要咖啡,latte,cappuccino,mocha都在我的範圍內,但礦泉水就不在了。
換句話說,我們要把高層要求做Specific,就需要在自己想控制的範圍內,把所有的選擇都選擇了。如果我們能把所有選擇都選擇了,我們哪裡需要“高層設計”呢?我們做高層設計的目的,就是為了在陷入細節選擇之前,把一些模糊的點挑出來,看看這些點本身,在邏輯上是否可以自恰。我們是在做反向校驗,不是在做正向建模。而你現在想做一種工具,只要表述少數的邏輯,就可以表達你的選擇,這可能嗎?
我前幾天寫了一個關於InfiniBand邏輯空間的分析:ofollow,noindex" target="_blank">infiniband概念空間分析 ,從這個分析就很容易看出來,我們可以簡單說MR,就說明了所有對記憶體的要求,前提就是定義這個名稱的細節,並保證這個細節可以解決特定領域的問題。這本質是什麼?這本質是抽象。在特定的領域,某些選擇具有共性,所以我們可以抽象,並定義它的細節。這種定義,一點離開了那個環境(比如這個例子中從RDMA進入本地加速器這個領域),就不再有效的。然後你想就某種語言為基礎,直接定義一個工具進行這種轉換?這不是緣木求魚嗎?
所以,所謂模型直接編碼,它不是不行,本質上它是定義一種DSL,你得把心思放在DSL本身的問題上,而不是工具上。前兩天我還聽了一個軟體架構的Podcasts,嘉賓是Humane Assessment Method的作者(Tudor Girba),他有一個觀點說得很有道理:我們都覺得我們可以發明一些工具,把已有的邏輯,通過這些工具來解決。但我們卻沒有注意到,如果這些邏輯可以通過工具來解決,這裡面必然包含了特定的邏輯,這些邏輯必然是相對固定的。但我們編碼的時候卻其實不斷在解決新的問題……既然如此,我們發明這些工具的意義在什麼地方呢?
當然,這個問題是可以回答的:這些工具的意義在於固化邏輯。但既然如此,我們的工作就不是如何做這個工具,而是如何找到這種固化的邏輯,並且固化它,否則進行這樣的語義定義是沒有意義的。更不要說現在大部分所謂架構模型生成程式碼的努力,表達能力遠遠不如普通程式語言的表達能力,這相當於讓你一個只有英語4級的中國人用英語去討論哲學問題,這個東西怎麼可能討論得清楚?
形式化驗證是一樣的,如果形式化驗證本身的模型語言可以表達得和C一樣,我們何必用C來寫程式碼呢?C程式碼中的每個轉折,都有其邊界效應在的呀(比如記憶體和Cache的速度問題,Memory Barrier問題等),這些邊界效應本身就是它功能的一部分啊,你憑什麼認為形式化驗證建模可以約束這些邊界效應?
到頭來,這裡沒有銀彈,大部分情況下,核心還是你基於現實的邏輯推演,這代表我們今天程式碼的大部分。