C 使用Fluent API 建立自己的DSL

2022-10-11 17:33:11 字數 3741 閱讀 5115

dsl(domain specified language)領域專用語言是描述特定領域問題的語言,聽起來很唬人,其實不是什麼高深的東西。看一下下面的**:

using flunetapidemo;

var 張三 = "張三"

.是學生()

.身高(1.62m)

.體重(48m);

console.writeline(張三.bmi());

console.writeline(張三.bmi狀態());

這段**根據學生的身高體重,計算bmi並判斷狀態(偏瘦、正常、超重還是肥胖),看到這裡,各位同學可能已經發現問題了:學生有小學生、中學生和大學生,難道計算演算法一樣?男生女生的計算演算法也一樣?在這個問題中,各位都是領域專家,從我寫的描述特定問題的**中發現了問題,我需要對**進行修改,增加年齡和性別因素。

從上面的例子可以看到dsl的作用:是解決領域專家與軟體開發人員之間的溝通問題。領域專家通常不懂得程式設計,無法判斷開發人員寫的**是否符合領域的要求,只能是等到軟體編寫完成,從軟體執行表現出來的功能進行判斷,而這時成本已經發生了,幾個來回下來,進度超時,成本超支。dsl使用領域相關的術語編寫,領域專家可以理解,而語言本身基於某種宿主語言,比如c#,可以編譯執行,容易驗證。所以恰當的dsl可以打通領域專家和開發人員之間的障礙,使軟體的業務核心部分開發可靠並有效率。「可以執行」是dsl與需求階段使用的偽語言或者帶圖示的自然語言最大的不同。在需求描述的時候,經常使用各種圖示或者偽語言對業務進行描述,偽語言一般是一種類似的結構化語言,這種貌似語言的東西往往是很有害的,因為只是大概描述了過程,很多實現細節被忽略或者隱藏了。由於不是嚴格的程式語言,無法生成可執行的**,所以也就無法驗證對錯。

結合上面的例子,我們看一下如何使用fluent api建立自己的dsl。其使用的技術實質上是實現現有型別的擴充套件,這需要我們1)宣告乙個static類,2)在類中使用static函式,3)使用this關鍵字修飾需要擴充套件的型別。上面的"張三".是學生(),「是學生」是字串型別的乙個擴充套件,返回的是自己定義的student型別,這段**如下:

namespace flunetapidemo

; }

public static student 身高(this student student,decimal height)

public static student 體重(this student student, decimal weight)

public static decimal bmi(this student student)

public static string bmi狀態(this student student)

}}

在student類中只定義關鍵屬性:

namespace flunetapidemo

=string.empty;

public decimal height

public decimal weight

public override string tostring()

}}

怎麼樣,挺簡單的吧。完整的**上傳到github: 

最後的問題是**中的中文問題,我的原則是怎麼方便怎麼來,通常我們編寫程式時不主張使用中文作為變數或者方法名稱,儘管現代程式語言的編譯器很多已經不限於只支援ascii碼,但我們仍然無法確保在某些情況下不出現問題(比如如果將中文命名的方法對映為web api介面,不支援中文的客戶端可能無法呼叫這個api)。然而作為領域特定語言的dsl就不用有這個限制,dsl的主要目的就是溝通,如果必須用英文或者漢語拼音進行編寫,效果就會大打折扣,更不用說很多領域都是中文為主的,這裡不展開說了,舉幾個例子,「唐詩」、「宋詞」、「元曲」估計翻成英語領域專家和程式設計師都看不懂。

dsl(domain specified language)領域專用語言是描述特定領域問題的語言,聽起來很唬人,其實不是什麼高深的東西。看一下下面的**:

using flunetapidemo;

var 張三 = "張三"

.是學生()

.身高(1.62m)

.體重(48m);

console.writeline(張三.bmi());

console.writeline(張三.bmi狀態());

這段**根據學生的身高體重,計算bmi並判斷狀態(偏瘦、正常、超重還是肥胖),看到這裡,各位同學可能已經發現問題了:學生有小學生、中學生和大學生,難道計算演算法一樣?男生女生的計算演算法也一樣?在這個問題中,各位都是領域專家,從我寫的描述特定問題的**中發現了問題,我需要對**進行修改,增加年齡和性別因素。

從上面的例子可以看到dsl的作用:是解決領域專家與軟體開發人員之間的溝通問題。領域專家通常不懂得程式設計,無法判斷開發人員寫的**是否符合領域的要求,只能是等到軟體編寫完成,從軟體執行表現出來的功能進行判斷,而這時成本已經發生了,幾個來回下來,進度超時,成本超支。dsl使用領域相關的術語編寫,領域專家可以理解,而語言本身基於某種宿主語言,比如c#,可以編譯執行,容易驗證。所以恰當的dsl可以打通領域專家和開發人員之間的障礙,使軟體的業務核心部分開發可靠並有效率。「可以執行」是dsl與需求階段使用的偽語言或者帶圖示的自然語言最大的不同。在需求描述的時候,經常使用各種圖示或者偽語言對業務進行描述,偽語言一般是一種類似的結構化語言,這種貌似語言的東西往往是很有害的,因為只是大概描述了過程,很多實現細節被忽略或者隱藏了。由於不是嚴格的程式語言,無法生成可執行的**,所以也就無法驗證對錯。

結合上面的例子,我們看一下如何使用fluent api建立自己的dsl。其使用的技術實質上是實現現有型別的擴充套件,這需要我們1)宣告乙個static類,2)在類中使用static函式,3)使用this關鍵字修飾需要擴充套件的型別。上面的"張三".是學生(),「是學生」是字串型別的乙個擴充套件,返回的是自己定義的student型別,這段**如下:

namespace flunetapidemo

; }

public static student 身高(this student student,decimal height)

public static student 體重(this student student, decimal weight)

public static decimal bmi(this student student)

public static string bmi狀態(this student student)

}}

在student類中只定義關鍵屬性:

namespace flunetapidemo

=string.empty;

public decimal height

public decimal weight

public override string tostring()

}}

怎麼樣,挺簡單的吧。完整的**上傳到github: 

最後的問題是**中的中文問題,我的原則是怎麼方便怎麼來,通常我們編寫程式時不主張使用中文作為變數或者方法名稱,儘管現代程式語言的編譯器很多已經不限於只支援ascii碼,但我們仍然無法確保在某些情況下不出現問題(比如如果將中文命名的方法對映為web api介面,不支援中文的客戶端可能無法呼叫這個api)。然而作為領域特定語言的dsl就不用有這個限制,dsl的主要目的就是溝通,如果必須用英文或者漢語拼音進行編寫,效果就會大打折扣,更不用說很多領域都是中文為主的,這裡不展開說了,舉幾個例子,「唐詩」、「宋詞」、「元曲」估計翻成英語領域專家和程式設計師都看不懂。

C 使用FluentAPI建立自己的DSL 推薦

dsl的作用是解決領域專家與軟體開發人員之間的溝通問題。聽起來很唬人,其實不是什麼高深的東西,我們可以使用fluent api 建立自己的dsl dsl domain specified language 領域專用語言是描述特定領域問題的語言,聽起來很唬人,其實不是什麼高深的東西。看一下下面的 us...

Oracle使用序列建立自增字段

在oracle中sequence就是所謂的序列號,每次取的時候它會自動增加,一般用在需要按序列號排序的地方。1 create sequence 你首先要有create sequence或者create any sequence許可權 sql create sequence seq emp incre...

Oracle使用序列建立自增字段

在oracle中sequence就是所謂的序列號,每次取的時候它會自動增加,一般用在需要按序列號排序的地方。1 create sequence 你首先要有create sequence或者create any sequence許可權 sql create sequence seq emp incre...