国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何設(shè)計(jì)領(lǐng)域特定語(yǔ)言,實(shí)現(xiàn)終極業(yè)務(wù)抽象?

開(kāi)發(fā) 后端
本文所寫(xiě)的皆是外部 DSL,即『不同于應(yīng)用系統(tǒng)主要使用語(yǔ)言』的語(yǔ)言。創(chuàng)建外部 DSL 和創(chuàng)建一種通用目的的編程語(yǔ)言的過(guò)程是相似的,它可以是編譯型或者解釋型的。

[[404312]]

在過(guò)去的幾年里,我一直從事于各種領(lǐng)域定義語(yǔ)言的設(shè)計(jì),包含 unflow、guarding、datum、forming 等。在我剛?cè)腴T(mén)這個(gè)領(lǐng)域的時(shí)候,我從《領(lǐng)域特定語(yǔ)言》、《編程語(yǔ)言實(shí)現(xiàn)模式》 等,一直研究到龍書(shū)等。我漸漸掌握了領(lǐng)域特定語(yǔ)言設(shè)計(jì)的一些技巧,也能快速(相對(duì)于過(guò)去)設(shè)計(jì)出一個(gè)領(lǐng)域特定語(yǔ)言。

所以,我在想我應(yīng)該總結(jié)一下相關(guān)的套路。這樣一來(lái),也可以在未來(lái)驗(yàn)證現(xiàn)在的思路是否正確:

  1. 定義呈現(xiàn)模式。
  2. 提煉領(lǐng)域特定名詞。
  3. 設(shè)計(jì)關(guān)聯(lián)關(guān)系與語(yǔ)法。
  4. 實(shí)現(xiàn)語(yǔ)法解析。
  5. 演進(jìn)語(yǔ)言的設(shè)計(jì)。

領(lǐng)域特定語(yǔ)言

領(lǐng)域特定語(yǔ)言(英語(yǔ):domain-specific language、DSL)指的是專注于某個(gè)應(yīng)用程序領(lǐng)域的計(jì)算機(jī)語(yǔ)言。

本文所寫(xiě)的皆是外部 DSL,即『不同于應(yīng)用系統(tǒng)主要使用語(yǔ)言』的語(yǔ)言。創(chuàng)建外部 DSL 和創(chuàng)建一種通用目的的編程語(yǔ)言的過(guò)程是相似的,它可以是編譯型或者解釋型的。

通用目的編程語(yǔ)言的源代碼和外部 DSL 的源代碼之間的主要區(qū)別在于,經(jīng)過(guò)編譯的 DSL 通常不會(huì)直接產(chǎn)生可執(zhí)行的程序(但是它確實(shí)可以)。大多數(shù)情況下,外部 DSL 可以轉(zhuǎn)換為一種與核心應(yīng)用程序的操作環(huán)境相兼容的資源,也可以轉(zhuǎn)換為用于構(gòu)建核心應(yīng)用的通用目的編程語(yǔ)言。—— Vaughn Vernon

簡(jiǎn)單場(chǎng)景下的領(lǐng)域特定語(yǔ)言,只是將特定的源碼轉(zhuǎn)換為特定的數(shù)據(jù)結(jié)構(gòu)。如 JSON 便是一種 DSL,在 Java 語(yǔ)言里,需要將它轉(zhuǎn)換為對(duì)應(yīng)的數(shù)據(jù)類。復(fù)雜場(chǎng)景下的領(lǐng)域特定語(yǔ)言,可以直接編譯為可執(zhí)行程序。

外部 DSL 的麻煩點(diǎn)在于:

  • 語(yǔ)法設(shè)計(jì)
  • 語(yǔ)法解析
  • IDE 支持

當(dāng)然了,它的優(yōu)點(diǎn)也很明顯:

  1. 讓不懂編程的業(yè)務(wù)專家(領(lǐng)域?qū)<?快速編寫(xiě)核心邏輯。
  2. 領(lǐng)域邏輯與具體編程語(yǔ)言無(wú)關(guān)
  3. 平臺(tái)無(wú)關(guān)。

更多的信息,建議去閱讀《領(lǐng)域特定語(yǔ)言》一書(shū)。

定義呈現(xiàn)模式

領(lǐng)域特定語(yǔ)言嘛,從需求上就是對(duì)于業(yè)務(wù)呈現(xiàn)的簡(jiǎn)化。根據(jù)不同的呈現(xiàn)模式,去解析源碼,得到我們所需要的數(shù)據(jù)結(jié)構(gòu)。

呈現(xiàn)模式

如下是常見(jiàn)的的領(lǐng)域特定語(yǔ)言的使用模式 [wiki_dsl]:

  • 獨(dú)立的工具,如 Makefile
  • 在編譯時(shí)或?qū)崟r(shí)轉(zhuǎn)換為宿主語(yǔ)言
  • 嵌入式領(lǐng)域特定語(yǔ)言
  • ……

可以參見(jiàn)維基百科,我就不再去翻譯了。

[wikidsl]: https://en.wikipedia.org/wiki/Domain-specificlanguage

定義數(shù)據(jù)結(jié)構(gòu)

從通用語(yǔ)言的編譯過(guò)程來(lái)看:

  1. 詞法分析器,分析輸入的字符流,得到符號(hào)流。
  2. 語(yǔ)法分析,分析符號(hào)流,得到語(yǔ)法樹(shù)
  3. 語(yǔ)義分析,分析語(yǔ)法樹(shù),得到新的語(yǔ)法樹(shù)
  4. 中間代碼生成器,分析語(yǔ)法樹(shù),得到中間表示形式
  5. ……

步驟 1~4,對(duì)于通用語(yǔ)言和領(lǐng)域特定語(yǔ)言來(lái)說(shuō)都是極為類似的。唯一擁有區(qū)別的是這個(gè)中間表示形式,對(duì)于領(lǐng)域特定語(yǔ)言來(lái)說(shuō),我們場(chǎng)景的原因,這里往往是我們所需要的數(shù)據(jù)結(jié)構(gòu)。

當(dāng)然了,從某種意義上來(lái)說(shuō),AST(抽象語(yǔ)法樹(shù))也是一種數(shù)據(jù)結(jié)構(gòu),只不過(guò)它是一種中間的數(shù)據(jù)結(jié)構(gòu)。所以,有時(shí)候在設(shè)計(jì)的時(shí)候,我就偷懶直接輸出中間表示了。

提煉領(lǐng)域特定名詞

這個(gè)環(huán)節(jié)的過(guò)程,實(shí)現(xiàn)上和 DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))里的提煉問(wèn)題域以獲取領(lǐng)域知識(shí)是頗為相似的。同樣的這個(gè)過(guò)程中,通過(guò)與領(lǐng)域?qū)<业膮f(xié)作,我們才能獲得更好的領(lǐng)域特定語(yǔ)言。

從用例開(kāi)始

用例,或譯使用案例、用況,是軟件工程或系統(tǒng)工程中對(duì)系統(tǒng)如何反應(yīng)外界請(qǐng)求的描述,是一種通過(guò)用戶的使用場(chǎng)景來(lái)獲取需求的技術(shù)。

在進(jìn)行領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)協(xié)作時(shí),我們需要與領(lǐng)域?qū)<依斫庥脩粼谶@個(gè)過(guò)程中,進(jìn)行的一系列操作,以提煉我們所需要的統(tǒng)一語(yǔ)言。而其中的用例能描述達(dá)到目標(biāo)所需的步驟,包含用戶和系統(tǒng)之間的交互。

在創(chuàng)建領(lǐng)域特定語(yǔ)言的時(shí)候,這個(gè)過(guò)程對(duì)于我們來(lái)說(shuō),也是類似的:與領(lǐng)域?qū)<乙黄饏f(xié)作,從用例開(kāi)始提煉。它也可以直接由現(xiàn)有的代碼中提煉而來(lái)。

從已有用例入手

對(duì)于已有系統(tǒng)來(lái)說(shuō),用例可以由:

與領(lǐng)域?qū)<医涣鳙@取。與領(lǐng)域?qū)<伊奶欤俏覀儷@得用例的最好方式。記錄用例,從而獲得關(guān)鍵信息。

從現(xiàn)有的代碼中提取。

在 ArchUnit 中提取架構(gòu)規(guī)劃上的設(shè)計(jì)便是:

  1. classes().that().resideInAPackage("..foo.."
  2. .should().onlyHaveDependentClassesThat().resideInAnyPackage("..source.one..", "..f 

對(duì)應(yīng)的,我們?cè)?Guarding 的設(shè)計(jì)是:

  1. class(resideIn "..foo..") dependent package(resideIn ["..source.one..""..foo.."

在 Guarding 中設(shè)計(jì)的是針對(duì)主流的編程語(yǔ)言,所以在語(yǔ)法上會(huì)盡量與編程語(yǔ)言無(wú)關(guān)。

提取關(guān)鍵字、值、屬性

在獲得了用例作為輸入條件之后,我們就需要從中提取一些關(guān)鍵信息,如關(guān)鍵字、值、屬性等等。

如下是我在設(shè)計(jì) Guarding DSL 時(shí),從 ArchUnit 提取的一小部分關(guān)鍵信息:

  1. package: 
  2.   dependOn 
  3.  
  4. class: 
  5.   implement 
  6.   annotation 
  7.   annotatedWith 
  8.  
  9. expression: 
  10.   and 
  11.   or 
  12.   not 
  13.   equals 
  14.   only 

接著,我們就可以依據(jù)這些信息,展開(kāi)它們的關(guān)聯(lián)設(shè)計(jì),進(jìn)而設(shè)計(jì)我們的語(yǔ)法。

設(shè)計(jì)關(guān)聯(lián)關(guān)系與語(yǔ)法

在設(shè)計(jì)領(lǐng)域特定語(yǔ)言時(shí),我們主要以實(shí)現(xiàn)領(lǐng)域中的用例作為目標(biāo):

  1. 使用 DSL 描述一個(gè)用例
  2. 先不考慮語(yǔ)法實(shí)現(xiàn),實(shí)現(xiàn)大部分用例的 DSL 草稿版本
  3. 對(duì)齊不同用例 DSL 中的差異
  4. 考慮一些非常規(guī)的用例,添加額外的屬性

名詞關(guān)系與邏輯設(shè)計(jì)

領(lǐng)域特定語(yǔ)言,所針對(duì)的是特定領(lǐng)域。在特定的領(lǐng)域里,都會(huì)使用特定的詞匯來(lái)描述相關(guān)之間的關(guān)系。這個(gè)關(guān)系,便是我們?cè)O(shè)計(jì)語(yǔ)法的一個(gè)關(guān)鍵。

如在 Java 語(yǔ)言里,使用: implement、 extends 來(lái)表示兩個(gè)類之間的關(guān)系。而為了表示包之間的關(guān)系,則會(huì)有: dependent、 resideIn 等等的關(guān)系。

實(shí)現(xiàn)用例

實(shí)現(xiàn)用例并不是一個(gè)復(fù)雜的過(guò)程,只是要符合人類的思維習(xí)慣,并盡可能地簡(jiǎn)化設(shè)計(jì)。不過(guò),覺(jué)得注意的是,我們應(yīng)該留下一些證據(jù)來(lái)告訴未來(lái)的自己:我們當(dāng)時(shí)是為什么考慮的。

在設(shè)計(jì) DSL 時(shí),我往往會(huì)創(chuàng)建一個(gè) sample 文件,以記錄過(guò)程中,對(duì)于不同的要素的思索。如我在設(shè)計(jì) Guarding DSL 里,使用了一個(gè) 0.0.1.sample 文本文件,來(lái)描述早期版本的語(yǔ)法示例:

  1. # 正則表達(dá)式 
  2. package(match("^/app")) endsWith "Connection"
  3.  
  4. package("..home..")::name should not contains(matching("")); 
  5.  
  6. # 簡(jiǎn)化的比較 
  7. class::name.len should < 20; 

通過(guò)一些注釋來(lái)讓自己優(yōu)化設(shè)計(jì)。

實(shí)現(xiàn)語(yǔ)法解析

這一部分的過(guò)程,和我們學(xué)習(xí)編譯原理時(shí)基本是一致的。不過(guò)呢,在編寫(xiě)領(lǐng)域特定語(yǔ)言的時(shí)候,我們一般會(huì)使用解析器生成器,而不是手寫(xiě)解析器。

細(xì)節(jié)設(shè)計(jì)

設(shè)計(jì)領(lǐng)域特定語(yǔ)言的時(shí)候,在設(shè)計(jì)語(yǔ)法上的拘束不會(huì)像通用語(yǔ)言那么多。所以,自由設(shè)計(jì)的范圍就大一點(diǎn),有些內(nèi)容也不一定需要像編程語(yǔ)言麻煩。諸如于:

  • 分隔符
  • 縮進(jìn)的處理
  • 語(yǔ)法塊的開(kāi)始和結(jié)束
  • ……

PS:使用類似于編程語(yǔ)言的寫(xiě)法,對(duì)于寫(xiě) DSL 的非編程人士來(lái)說(shuō)可能會(huì)變成一種困擾。

解析器生成器

經(jīng)典的 Lex & Yacc 是你可以考慮的范圍,在不同的語(yǔ)言里也有一些相似的實(shí)現(xiàn)。

對(duì)于我來(lái)說(shuō),以下是我常用的一些解析器生成器。

  • Antlr。支持主流的語(yǔ)言
  • Peg.js。JavaScript
  • Pest。Rust
  • Lalrpop。Rust

我還是比較習(xí)慣用 Antlr,支持的語(yǔ)言較多。我與同事以及開(kāi)源社區(qū)的小伙伴們,在下面的項(xiàng)目中都使用過(guò) Antlr:

  • Coca = Golang + Antlr
  • Unflow = Rust + Antlr
  • Lemonj = JavaScript/TypeScript + Antlr
  • Chapi = Java/Kotlin + Antlr

從使用上它們之間的差距并不大,但是都需要學(xué)習(xí)成本。

演進(jìn)語(yǔ)言的設(shè)計(jì)

最后,讓我們來(lái)談?wù)勔恍┯幸馑嫉臇|西,雖說(shuō)是演進(jìn)吧,但是,和設(shè)計(jì)暫時(shí)沒(méi)有太大的關(guān)系。

測(cè)試驅(qū)動(dòng)開(kāi)發(fā)

經(jīng)我大量發(fā)現(xiàn),TDD 是非常適合于編程語(yǔ)言的開(kāi)發(fā)與設(shè)計(jì)。需求是未知的,易于發(fā)生變化的,還需要覆蓋足夠全的場(chǎng)景。

從實(shí)踐的層面上來(lái)說(shuō),主要是有兩種:

  1. 面向語(yǔ)法的測(cè)試。即,只讓語(yǔ)法編譯能通過(guò),但是不報(bào)錯(cuò)。
  2. 面向功能的測(cè)試。即,驗(yàn)證某一部分的語(yǔ)法是正確的。
  3. 面向用例的測(cè)試。即,驗(yàn)證符合使用場(chǎng)景。

自動(dòng)化語(yǔ)言遷移

原先這部分的標(biāo)題是,向下兼容。但是,我一直覺(jué)得向下兼容不是一個(gè)好主意。所以呢,我就想了想把在其它領(lǐng)域的經(jīng)驗(yàn)搬了過(guò)來(lái),于是呢,內(nèi)容就變成了自動(dòng)化語(yǔ)言遷移。

在關(guān)于版本的遷移上,我覺(jué)得 Angular 語(yǔ)言上關(guān)于版本的自動(dòng)化遷移,是值得我們?nèi)ソ梃b的。當(dāng)然了,采用這種設(shè)計(jì)的成本非常高,我們需要有一個(gè)專門(mén)的團(tuán)隊(duì),使用工具自動(dòng)化分析舊的系統(tǒng),并使用工具來(lái)自動(dòng)修改舊的代碼。

其它

文中相關(guān) DSL 鏈接(歡迎加入 Inherd 一起編寫(xiě) DSL):

Unflow: https://github.com/inherd/unflow

Guarding: https://github.com/inherd/guarding

Forming: https://github.com/inherd/forming

本文轉(zhuǎn)載自微信公眾號(hào)「phodal」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系phodal公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: phodal
相關(guān)推薦

2020-03-04 11:20:22

DSL開(kāi)發(fā)領(lǐng)域特定語(yǔ)言

2009-03-12 14:31:15

QCon

2025-05-30 01:33:00

2022-06-17 11:04:47

語(yǔ)法分析器GoyaccAST

2014-09-26 10:00:25

驅(qū)動(dòng)設(shè)計(jì)DDD領(lǐng)域

2014-09-11 15:05:40

驅(qū)動(dòng)設(shè)計(jì)驅(qū)動(dòng)開(kāi)發(fā)

2023-08-29 08:57:03

事務(wù)腳本架構(gòu)模式業(yè)務(wù)場(chǎng)景

2024-08-19 14:06:00

2022-01-28 14:20:53

前端代碼中斷

2009-08-27 09:16:48

F#中DSL原型設(shè)計(jì)

2024-01-22 15:36:54

大語(yǔ)言模型人工智能

2023-11-27 15:34:51

大語(yǔ)言模型PubMedBERT

2010-01-25 09:17:01

Visual Stud

2023-02-13 07:04:12

VBC#語(yǔ)言

2024-07-17 08:36:53

2018-05-21 07:08:18

行為驅(qū)動(dòng)開(kāi)發(fā)BDD編碼

2009-11-13 19:54:42

2021-06-30 07:51:09

新項(xiàng)目領(lǐng)域建模

2020-04-13 09:54:44

微服務(wù)子集存儲(chǔ)

2009-10-13 17:08:10

CLR VB.NET
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

成人av资源在线播放| 国产福利91精品一区二区三区| 超碰国产在线观看| 天堂电影在线| 国产精品欧美三级在线观看| 国产欧美精品日韩区二区麻豆天美| 亚洲欧洲午夜一线一品| 日本一区二区三区四区五区六区| 国产网站在线| 国产在线精品一区在线观看麻豆| 亚洲娇小xxxx欧美娇小| 一区二区三区四区在线视频| 操喷在线视频| 国产精品综合二区| 久久精品国产亚洲| 久久久久久蜜桃一区二区| 黄色美女久久久| 亚洲免费伊人电影| 国产在线日韩在线| 久草视频视频在线播放| 99成人在线| 日韩精品欧美激情| 九色自拍视频在线观看| 一区二区三区四区高清视频| 亚洲靠逼com| 狠狠热免费视频| 成人看的视频| 欧美老女人在线| 亚洲国产另类久久久精品极度| 成全电影大全在线观看| 欧美日韩亚洲综合一区| 黄色一级视频播放| 免费人成网站在线观看欧美高清| 色偷偷88888欧美精品久久久| 日本免费观看网站| 国产日韩在线不卡| 51国偷自产一区二区三区 | 狠狠干狠狠久久| 青青影院一区二区三区四区| 国产91欧美| 欧美色视频日本版| 在线播放欧美女士性生活| 97超碰在线资源站| 色先锋久久影院av| 欧洲精品视频在线观看| 免费的一级黄色片| 亚洲综合小说图片| 亚洲成人黄色网址| 日韩av卡一卡二| 亚洲欧美一区二区久久| 国产伦精品一区二区三区照片91 | 久久久这里只有精品视频| 欧美男男同志| 成人午夜在线播放| 草莓视频一区| jizz性欧美23| 日韩精品影音先锋| 三上悠亚一区| 羞羞的视频免费| 性一交一乱一区二区洋洋av| 久久青草福利网站| 欧洲杯足球赛直播| 日韩一区在线视频| 日韩av激情| 欧美日韩色婷婷| av网址在线免费观看| 一区二区在线免费| 可以在线看的黄色网址| 一本久道久久综合狠狠爱| 99中文字幕在线观看| 中文字幕一区二区三区乱码图片| 欧美国产日韩视频| www.51av欧美视频| 久久久久久美女| 人人鲁人人莫人人爱精品| 在线精品国精品国产尤物884a| 成人性生交大片免费看网站| 性色av一区二区三区在线观看| 韩日精品一区二区| 91极品视觉盛宴| 四虎4hutv紧急入口| 国产激情91久久精品导航 | 色视频在线观看福利| 北条麻妃国产九九精品视频| 日本一区二区精品视频| 久久亚洲私人国产精品va媚药| 秋霞在线一区二区| 一本色道久久综合亚洲精品不| 国产xxxxx在线观看| 国产成人在线观看| 天堂v视频永久在线播放 | 欧美xxxx吸乳| 欧美日韩免费在线| 久久伊人精品| 久久精彩免费视频| 99精品视频免费观看视频| 无码aⅴ精品一区二区三区浪潮 | 国产91在线亚洲| 欧美吻胸吃奶大尺度电影 | 欧美激情一区二区三区在线视频观看 | 国产在线一区二| 欧美精品国产| 成人日韩在线电影| 久久久久久麻豆| 国产日韩一区二区在线观看| 欧美日韩精品一区二区| 成av人电影在线观看| 久久免费国产视频| 高清不卡在线观看av| 国产精品久久中文字幕| 成人18精品视频| 久草免费福利在线| 久久综合一区二区| 17videosex性欧美| 日韩精品久久久久久久玫瑰园| 国产精品国产一区| 成人av蜜桃| 亚洲欧美日韩国产中文在线| 久久国产三级| 高清亚洲成在人网站天堂| 久久一综合视频| 国产又大又长又粗又黄| 欧美精选一区二区| 精品9999| 免费h精品视频在线播放| 精品一区二区三区免费毛片爱| 精品少妇人欧美激情在线观看| 欧美日韩综合在线| 在线一区免费| 日韩a在线观看| 91系列在线观看| 免费成人av在线播放| 麻豆av在线导航| 一区二区三区在线视频播放| 亚洲欧美专区| 国产激情999| 欧美freesex交免费视频| 日韩精品无码一区二区三区| 丁香另类激情小说| 激情aⅴ欧美一区二区欲海潮| 亚洲人成影视在线观看| xnxx国产精品| 中文字幕在线第一页| 日韩一区二区电影网| 亚洲承认视频| 51精品国产黑色丝袜高跟鞋| 久久精品影视| 伊人婷婷久久| 亚洲国产精品va在线观看黑人| 另类小说视频一区二区| 美女一区二区三区视频| 久久久久久久色| 亚洲免费观看高清完整版在线| 国产综合久久久| 日韩毛片在线一区二区毛片| 官网99热精品| 91视频一区二区| 精品亚洲二区| 国产精品三级a三级三级午夜| 日韩一级大片在线观看| 免费久久精品视频| 精品欧美一区二区三区在线观看 | 91精品久久久| 国产日韩欧美成人| 精品久久久久久久久中文字幕| 免费99热在线观看| 欧美有码在线观看视频| 无码av中文一区二区三区桃花岛| 欧美激情第8页| 色婷婷在线播放| 天堂8在线天堂资源bt| 亚洲va欧美va人人爽午夜 | 亚洲女厕所小便bbb| 偷偷www综合久久久久久久| www在线免费观看视频| 国自在线精品视频| 天天爽夜夜爽夜夜爽精品视频| 综合精品久久| 暧暧视频在线免费观看| 成熟老妇女视频| 亚洲影院污污.| 中文字幕精品—区二区四季| 亚洲电影视频在线| 久久久久久久9| 人人爽久久涩噜噜噜网站| 老司机精品视频一区二区三区| 欧美亚洲人成在线| 精品国产乱码久久久久久久软件| 欧美激情一区二区三区全黄 | 三年片观看免费观看大全视频下载| 成人在线看片| 怡红院精品视频| 裸体一区二区| av电影资源| xxxxx成人.com| 午夜精品福利一区二区蜜股av| 免费欧美在线视频| 国产麻豆精品久久| 日韩欧美少妇| 成人免费黄色网页|