使用DSL表達軟體設計意圖 - guitarvydas

banq發表於2022-04-05

我們目前還沒有一種用於DI(Design Intent設計意圖的簡稱,意圖包括架構,業務規則)的語言。
當DI被嵌入到了程式碼中的會出現病症:如果你需要重構,那麼很可能程式碼還沒有被切分為DI和實現兩個部分。

過多的細節走向了DI的對立面。 
大多數語言都以他們有多少功能而自豪,而不是他們有多麼少的功能。 

當你建立DI時,你不想關心某樣東西是如何實現的(例如,陣列與列表)。
這種實現低層次的效率與效能是工程師所關心的,而不是架構師。

DSL是將DI與實現分開的一種方式。


不要做基礎語言已經做過的事情
讓底層基礎語言處理繁重的工作。

只有在省力的情況下才使用 DSL

  • 設計:使用DSL而不是使用詳細的HLL可以 "更好地 "表達一個設計嗎?
  • 架構的重用:DI(設計意圖,又稱架構)的重用比程式碼的重用更重要。程式碼很便宜,思考很困難。
  • 保持 "業務規則 "與程式碼分離:使用一種語言進行DI,另一種語言進行實現。
  • 編碼:使用DSL可以減少編碼時間嗎?
  • 自動化:讓DSL來寫程式碼; 編寫可以編寫程式的程式。


維護

  • 使用DSL能減少維護工作嗎?
  • 維護工程師可以更快理解DI(設計意圖)嗎?
  • DSL能為你執行D.R.Y.(Don't Repeat Yourself)嗎?
  • 維護工程師能否透過調整DSL更快地進行錯誤修復?
  • 維護工程師能否透過調整DSL來更快地完成功能升級?



儘量少寫程式碼

  • 建立小型DSL
  • 使用DSL減少編碼
  • 依靠基礎語言來完成重任
  • 使用比文字更多的東西:
    管理層使用圖表(例如在白板上)。
    程式設計師也應該使用圖表。
    在同一個文件中混合使用圖表和文字是可以的。
  • 圖表可以很容易地轉譯


圖可以很容易轉譯
考慮字形,而不是畫素。 使用回溯分析器(如Ohm、PROLOG等)。

Gedanken的例子:

  • 你怎麼知道4條線是否構成一個盒子[1]?
  • 你怎麼知道一個盒子是否比另一個盒子小? 
  • 如何知道較小的盒子是否與較大的盒子的邊緣相交? 
  • 你怎麼知道一段文字是否完全在一個盒子裡?
  • 你怎麼知道一個箭頭(一條榮耀的線)是否連線了兩個盒子?
  • 如果這條線是由許多小段組成的呢?
  • 你如何畫一個網路?
  • 如何畫一個狀態機?[。
  • 當你用橢圓代替方框時,有什麼變化?
  • 當你用彎曲的線代替直線段時,會有什麼變化?



當所有其他方法都失敗時:自動化
以某種方式自動生成程式碼。 使用一個漂亮的格式,使程式碼可以被人類閱讀。
你可以一直使用生成的程式碼,就像它是手工寫的一樣(由別人寫的)。


為什麼管理層痛恨DSL

  • 對DSL的(錯誤)認知
    管理層認為DSL寫作是一個浪費時間的漏洞。 這種印象是基於一種錯誤的觀念,即編寫DSL和編寫編譯器是一樣的。
    管理層看到了建立一個DSL的前期成本。 管理層知道如何衡量開發時間(和成本),但不知道如何衡量維護(理解)成本。
    管理層不可能僱傭那些已經理解特定DSL的可互換的單位,即程式設計師。
    理解一個DSL需要思考,理解一個產品設計也需要思考。 
  • 僱用
    目前,我們還不知道如何在簡歷的基礎上僱用思想家。 
  • 工程師的職業
    工程師行業在幾十年前就遇到了這個問題,即僱用思想家。 
    答案是把這個行業分成幾個部分。 
    如果你在大學裡學習了4年的課程,並獲得了工程學位,那麼你就被認為是一名工程師。
    在貿易學院學習兩年的人被認為是貿易人員。 
    其他人則被認為是工人和砌磚工人。
    為了使這一計劃發揮作用,各階層之間必須使用一種溝通方法--藍圖。


繞行

  • 工程中不使用繞行
    工程師在設計上蓋章(蓋章或簽字),並在法律上對他們的設計負責。
    砌磚工人可能會發現設計中的 "缺陷 "或 "改進",但他們從不對藍圖進行實質性的修改。 這些改動必須得到簽字工程師的批准。
    繞行的做法在勞動和工程中從未使用過。
  • 繞行是一種症狀
    當人們認為生成技術不是在所有情況下都有效時,就會使用繞行技術。
    繞行通常會造成意外的複雜性。
    如果你認為你需要繞行,那麼: 

  1. 證明這個符號在某些情況下不起作用
  2. 修正這個符號,不要把繞行當作創可貼。



藍圖
目前的程式語言不能像藍圖那樣使用。
目前的程式語言暴露了太多的細節,無法有效地用作通訊機制,如藍圖。
在我看來,答案就在於隔離。

圖紙
藍圖是暴露出很少細節的圖紙。
藍圖是由簡單的元素組成的。
目前的程式語言暴露了太多的細節,無法像藍圖在工程和建築中的使用方式那樣使用。

擴充套件性
進一步解釋:
軟體設計中的主要問題是可擴充套件性。
我們希望像樂高積木一樣把各個部分 "插 "起來。
更好的可擴充套件性意味著更少的依賴性。
早期的硬體設計人員在這方面是 "正確的"。 他們把令人難以置信的複雜裝置(由各種鐵鏽組成的半導體)建成晶片/IC(積體電路)。
晶片是黑盒子。 它們有一組輸入/輸出引腳。 晶片的內部是不可捉摸的--被包裹在不透明的環氧樹脂中。
除了透過晶片的引腳,沒有任何東西從晶片中漏出或進入晶片。

晶片的屬性是用容易測量的術語來描述的:

  • 一個引腳上的電壓
  • 一個引腳所需的電流
  • 給定一組輸入,輸出的圖/圖表
  • 時序。


然後,硬體設計者 "發現",晶片之間的點對點佈線導致了不可擴充套件的設計。
他們建立了一個(小的)層次結構--晶片安裝在插在背板上的電路板上。

最早的背板基本上是點對點的線束。 例如,我擁有的早期Wang文書處理器,其背板有大約400個引腳,允許一塊板上的晶片直接向另一塊板上的晶片傳送訊號。
然後,出現了S100匯流排。 它只有100個引腳。 它有很好的定義和記錄。 某些連線是不允許的,即使它們可以作為點對點的連線更有效地完成。
匯流排的概念導致了蘋果電腦的出現,並最終導致了IBM臺式電腦的出現。 (匯流排的定義不止一個,但市場將其淘汰了)。

軟體可以像晶片一樣構建嗎? 我認為是的。

我們需要分層次地構建軟體。
分而治之。
層次結構中的各層之間不能有任何洩漏。 ("任何東西 "包括像變數、型別、控制流、任何種類的依賴關係等等)。

嚴謹與權衡
工程學是關於做出權衡的。
工程師們並不努力去證明一個設計是有效的--他們只是在設計中建立安全係數。 
目前對可證明的軟體設計的追求不會導致工程的發展。 
我們需要的是對可能的權衡的描述,例如,它的執行速度有多快?需要多大的記憶體?需要多大的處理能力?什麼是故障安全裝置,"大紅按鈕"?如果它崩潰了,可以做什麼?它是否有一個 "已知的開始狀態"? 設計每個功能需要多少錢? 測試每個功能需要多少錢?有什麼利害關係? 它需要進行多徹底的測試? 最壞情況下的吞吐量是多少? 平均吞吐量是多少?MTBF是多少?它是單源的還是多源的,有什麼影響?

複雜性
我認為軟體是一個層次分明的黑盒子。 每個盒子的架構師選擇最佳方式來描述黑盒子的設計意圖。 工程師找出如何在 "I "上打點,在 "T "上打叉。 生產工程師找出如何測量並使黑匣子 "更有效",而編碼員則為實現黑匣子打下基礎。

黑匣子架構
我認為軟體是一個黑盒子的層次結構[3]。 每個盒子的架構師選擇最好的方式來描述一個黑盒子的設計意圖。 工程師想出如何在I上打點,在T上劃線。 生產工程師找出如何使黑匣子 "更有效",而編碼員則為黑匣子的實施打下基礎。

許多銀彈
一個好的架構師會有一個裝滿 "銀彈 "的工具帶。 也許一個問題最好用關係術語來描述,也許一個問題最好用狀態機來描述(還可以用圖來描述),也許一個問題可以用同步方式來分解,等等,等等。

PSLs
領域特定語言 (DSL) 與問題特定語言 (SPL):
我將使用術語PSL而不是DSL來強調每個問題+解決方案的特定問題。 
PSL的意思是特定問題的語言。 舊的術語,DSL,意味著特定領域的語言。
在我看來,"領域 "這個詞太寬泛了,我們必須把重點放在問題上,我們必須用專業化而不是泛化來解決具體問題。
 

相關文章