翻译:A DSL in 5 Languages(五种语言的DSL)
文章目錄
- 五種語言的DSL
- 問題
- 實例搜索準則
- RUBY
- 策略
- 例子
- 優勢
- python
- 戰略
- 例子
- 優勢
- 弱點
- PHP
- 戰略
- C#
- java
- 總結
英文原文見: https://blog.csdn.net/matlab2000/article/details/6006676
五種語言的DSL
我們為客戶提供5種編程語言的客戶庫:Ruby、Python、PHP、Cype和Java。每個庫都是用來幫助我們的客戶提出請求、解析響應和從網關檢索數據的。我們希望他們與Braintree進行簡單、直觀的整合。
維護5個客戶端庫意味著用5種語言編寫基本相同的功能。在很多情況下,這僅僅意味著句法上的差異。然而,有些特性非常復雜,因此每個庫中都應該使用稍微不同的方法。
一個例子是事務搜索。因為搜索可能有點復雜,所以我們決定在五個庫中的每個庫中創建一個領域特定語言(DSL)。
問題
我們希望事務搜索既容易閱讀,又足夠深以執行復雜的查詢。具體地說,我們希望允許搜索3種不同類型的字段:
- 文本字段(Text fields) — 查詢精確匹配、不匹配、字符串開頭、字符串結束和子字符串
- 多個值字段(Multiple value fields) — 使用一組預定義值進行查詢,并將返回匹配任何給定值的所有記錄
- 范圍字段(Range fields)— 使用下限、上限或兩者查詢(都包含)
將返回與所有標準匹配的資源集合。
實例搜索準則
下面的代碼示例假設用戶希望搜索滿足以下條件的事務:
- 訂單ID以“A2D”開頭
- 客戶網站以“.com”結尾
- 計費第一名等于“約翰”
- 身份被授權或解決
- 金額在10到20美元之間
RUBY
策略
在Ruby中,搜索方法生成一個搜索對象到一個塊。此對象包含構建搜索條件所需的方法。然后執行塊,并根據結果生成請求。Ruby還重載了==,!=、>=和<=文本和范圍搜索字段上的運算符。我們認為這可以提高可讀性并減少語法噪聲。
例子
collection = Braintree::Transaction.search do |search|search.order_id.starts_with "a2d"search.customer_website.ends_with ".com"search.billing_first_name == "John"search.status.in(Braintree::Transaction::Status::Authorized,Braintree::Transaction::Status::Settled)search.amount.between "10.00", "20.00" endcollection.each do |transaction|puts transaction.id end優勢
- 方法調用中不需要括號,這樣可以創建更可讀的語法
- 創建請求和執行搜索的單個步驟
- 運算符重載提高了可讀性
python
戰略
我們的Python解決方案使用了不同的方法,因為該語言缺少塊語法和多行lambda。搜索方法需要一個表示搜索條件的對象列表。這些對象中的每一個都是使用可讀的方法名內聯構建的。然后,搜索方法可以迭代所提供的對象以構建搜索請求。
和Ruby一樣,這個實現重載操作符==,!=、>和<用于文本和范圍字段上的操作。
例子
collection = Transaction.search([TransactionSearch.order_id.starts_with("a2d"),TransactionSearch.customer_website.ends_with(".com"),TransactionSearch.billing_first_name == "John",TransactionSearch.status.in_list([Transaction.Status.Authorized,Transaction.Status.Settled]),TransactionSearch.amount.between("10.00", "20.00") ])for transaction in collection.items:print transaction.id優勢
- 創建請求和執行搜索的單個步驟
- 易于動態創建條件
- 運算符重載提高了可讀性
弱點
- 重復TransactionSearch類名
- 文本列表作為參數
PHP
戰略
PHP實現與上面描述的Python解決方案類似,但感覺不太可讀。同樣,search方法需要一個搜索條件對象的列表,并且這些對象是在方法調用期間以內聯方式創建的。但是,類方法調用的::語法以及->operator-for-instance方法調用會使代碼變得更加嘈雜。
(以下暫略)
C#
暫略
java
暫略
總結
一般來說,DSL實現有3種類型:Fluent接口、可讀的內聯方法參數和塊。我們發現流暢的接口是靜態語言最有效的方法。對于Python和PHP,可讀的內聯方法參數似乎是最慣用的。Ruby社區傾向于使用基于塊的DSL,我們為Ruby實現選擇了這種方法。
在5種不同的語言中解決相同的問題是一個非常寶貴的經驗。雖然結果非常不同,但我們認為每個解決方案都是健壯的和可讀的。更重要的是,用這些語言工作有助于我們從相對公正的角度了解每種語言的優缺點。
如果你是一個使用這些語言的開發人員,我們很樂意聽到你的反饋。你將如何用你選擇的語言處理這個問題?
總結
以上是生活随笔為你收集整理的翻译:A DSL in 5 Languages(五种语言的DSL)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SOAP基础知识
- 下一篇: 【Python自然语言处理】中文分词技术