一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

5種語(yǔ)言下的DSL實(shí)現(xiàn)

 guitarhua 2013-08-19

我們(此處指的是Braintree)為用戶(hù)提供5種語(yǔ)言的客戶(hù)端庫(kù):Ruby,Python,PHP,C#和Java。每一個(gè)庫(kù)都是幫助我們的客戶(hù)構(gòu)建請(qǐng)求,分析響應(yīng)以及從網(wǎng)關(guān)中獲取數(shù)據(jù),我們希望他們可以簡(jiǎn)單和直覺(jué)化的集成Braintree。


維護(hù)5種客戶(hù)端庫(kù)意味著編寫(xiě)在5種語(yǔ)言中編寫(xiě)本質(zhì)上一樣的功能。許多情況下也就是語(yǔ)法不同而已,但是,一些特征足夠復(fù)雜保證每個(gè)庫(kù)有些輕微不同。


一個(gè)例子是交易查詢(xún),由于查詢(xún)有些復(fù)雜,我們決定為每個(gè)庫(kù)創(chuàng)建領(lǐng)域特定語(yǔ)言(DSL)


問(wèn)題

我們希望交易查詢(xún)可以很簡(jiǎn)單的讀以及運(yùn)行足夠復(fù)雜的查詢(xún),特別希望能夠同時(shí)查詢(xún)3中不同類(lèi)型域:

 

        文本域:查詢(xún)精確匹配,沒(méi)有匹配,以及起始字符串,結(jié)尾字符串和子串

       多個(gè)值域:用指定值查詢(xún)并反悔所有匹配記錄

       范圍域:用低邊界和高邊界查詢(xún)(包含所有)


一個(gè)所有匹配條件的資源將返回


查詢(xún)條件例子

下面的代碼例子假定用戶(hù)想要用下面的條件查詢(xún)交易:

  • order id 以 "a2d"開(kāi)始
  • 客戶(hù)站點(diǎn)以".com"結(jié)尾
  • 賬單第一個(gè)名字為"John"
  • 狀態(tài)可能為Authorized或Settled
  • 金額在10到20美元之間


Ruby

策略

    

     在ruby,search方法在block中生成一個(gè)搜索對(duì)象,該對(duì)象包含了必要的方法構(gòu)建查詢(xún)條件。block將執(zhí)行時(shí)request被構(gòu)建,然后返回結(jié)構(gòu)。Ruby重載了查詢(xún)域中的文本與范圍==,!=,>=<=操作方法,我們想要改進(jìn)可讀性和減少語(yǔ)法噪音。

例子

  1. collection = Braintree::Transaction.search do |search|  
  2.   
  3.   search.order_id.starts_with "a2d"  
  4.   
  5.   search.customer_website.ends_with ".com"  
  6.   
  7.   search.billing_first_name == "John"  
  8.   
  9.   search.status.in(  
  10.   
  11.     Braintree::Transaction::Status::Authorized,  
  12.   
  13.     Braintree::Transaction::Status::Settled  
  14.   
  15.   )  
  16.   
  17.   search.amount.between "10.00""20.00"  
  18.   
  19. end  
  20.   
  21. collection.each do |transaction|  
  22.   
  23.   puts transaction.id  
  24.   
  25. end  


優(yōu)勢(shì)

  • 在方法調(diào)用上創(chuàng)建可讀語(yǔ)法上沒(méi)有不必要的括號(hào)
  • 創(chuàng)建請(qǐng)求和運(yùn)行查詢(xún)上單個(gè)步驟
  • 操作符重載改進(jìn)了可讀性

劣勢(shì)

  • 重復(fù)search block變量


Python

策略

由于Python缺少block語(yǔ)法和多行的lambda,解決方法中使用不同的方式,search方法需要一個(gè)列表對(duì)象來(lái)表達(dá)查詢(xún)條件。每個(gè)這些對(duì)象為一個(gè)可讀的方法名,search方法迭代所有提供的對(duì)象來(lái)構(gòu)建search查詢(xún)。

類(lèi)似Ruby,該實(shí)現(xiàn)在文本和范圍域上重載了==, !=,><操作

例子

  1. collection = Transaction.search([  
  2.   
  3.     TransactionSearch.order_id.starts_with("a2d"),  
  4.   
  5.     TransactionSearch.customer_website.ends_with(".com"),  
  6.   
  7.     TransactionSearch.billing_first_name == "John",  
  8.   
  9.     TransactionSearch.status.in_list([  
  10.   
  11.         Transaction.Status.Authorized,  
  12.   
  13.         Transaction.Status.Settled  
  14.   
  15.     ]),  
  16.   
  17.     TransactionSearch.amount.between("10.00""20.00")  
  18.   
  19. ])  
  20.   
  21. for transaction in collection.items:  
  22.   
  23.     print transaction.id  


優(yōu)勢(shì)

  • 創(chuàng)建請(qǐng)求和運(yùn)行查詢(xún)上單個(gè)步驟
  • 容易動(dòng)態(tài)創(chuàng)建條件
  • 操作符重載改進(jìn)了可讀性

劣勢(shì)

  • 重復(fù)的TransactionSearch類(lèi)名
  • 迭代列表作為參數(shù)


PHP

策略

PHP實(shí)現(xiàn)類(lèi)似于上面描述的Python實(shí)現(xiàn),但是略微少了些可讀性。再次,search方式需要一個(gè)查詢(xún)條件的列表以及這些對(duì)象在調(diào)用時(shí)創(chuàng)建,::語(yǔ)法表示類(lèi)方法,->操作符表示實(shí)例方法,稍微使得代碼有些噪音

例子

  1. $collection = Braintree_Transaction::search(array(  
  2.   
  3.     Braintree_TransactionSearch::orderId()->startsWith('a2d'),  
  4.   
  5.     Braintree_TransactionSearch::customerWebsite()->endsWith('.com'),  
  6.   
  7.     Braintree_TransactionSearch::billingFirstName()->is('John'),  
  8.   
  9.     Braintree_TransactionSearch::status()->in(array(  
  10.   
  11.         Braintree_Transaction::AUTHORIZED,  
  12.   
  13.         Braintree_Transaction::SETTLED  
  14.   
  15.     )),  
  16.   
  17.     Braintree_TransactionSearch::amount()->between('10.00''20.00')  
  18.   
  19. ));  
  20.   
  21. foreach($collection as $transaction) {  
  22.   
  23.     print_r($transaction->id);  
  24.   
  25. }  


優(yōu)勢(shì)

  • 創(chuàng)建請(qǐng)求和運(yùn)行查詢(xún)上單個(gè)步驟
  • 容易動(dòng)態(tài)創(chuàng)建條件

劣勢(shì)

  • 重復(fù)的Braintree_TransactionSearch類(lèi)名
  • 迭代列表作為參數(shù)


C#

策略

由于在C#語(yǔ)言中的慣用選擇,使用接口作為DSL的基礎(chǔ),接口用來(lái)構(gòu)建TransactionSearchRequest對(duì)象用來(lái)表示查詢(xún)條件。方法鏈用來(lái)指定特別的查詢(xún)條件:名字表示查詢(xún)的域,后面跟隨該域查詢(xún)的限制,namerestriction對(duì)也是鏈方式。

注意現(xiàn)在需要兩個(gè)步驟來(lái)進(jìn)行查詢(xún),在實(shí)際查詢(xún)前首先構(gòu)建查詢(xún)條件,C#允許使用無(wú)括號(hào)的屬性下的字段名

TransactionSearchRequest然后傳遞給search方法,返回一個(gè)collection

例子

  1. TransactionSearchRequest searchRequest = new TransactionSearchRequest().  
  2.   
  3.     OrderId.StartsWith("a2d").  
  4.   
  5.     CustomerWebsite.EndsWith(".com").  
  6.   
  7.     BillingFirstName.Is("John").  
  8.   
  9.     Status.IncludedIn(  
  10.   
  11.         TransactionStatus.AUTHORIZED,  
  12.   
  13.         TransactionStatus.SETTLED  
  14.   
  15.     ).  
  16.   
  17.     Amount.Between(10.00M, 20.00M);  
  18.   
  19. ResourceCollection<Transaction> collection = gateway.Transaction.Search(  
  20.   
  21.     searchRequest  
  22.   
  23. );  
  24.   
  25. foreach (Transaction transaction in collection)  
  26.   
  27. {  
  28.   
  29.     Console.WriteLine(transaction.Id);  
  30.   
  31. }  


優(yōu)勢(shì)

  • 屬性下使用不需要指定名稱(chēng)的搜索域中添加括號(hào)
  • 接口提供了簡(jiǎn)單語(yǔ)法用來(lái)描述查詢(xún)條件

劣勢(shì)

  • 分步驟來(lái)查詢(xún)和構(gòu)建搜索


Java

策略

JAVA也使用接口作為DSL的基礎(chǔ),再次接口通過(guò)方法鏈來(lái)構(gòu)建TransactionSearchRequest對(duì)象。

在java中會(huì)看到額外的括號(hào)在查詢(xún)域名,因?yàn)?/span>java缺少屬性,我們感覺(jué)這降低代碼的可讀性。

例子:

  1. TransactionSearchRequest searchRequest = new TransactionSearchRequest().  
  2.   
  3.     orderId().startsWith("a2d").  
  4.   
  5.     customerWebsite().endsWith(".com").  
  6.   
  7.     billingFirstName().is("John").  
  8.   
  9.     status().in(  
  10.   
  11.         Transaction.Status.AUTHORIZED,  
  12.   
  13.         Transaction.Status.SETTLED  
  14.   
  15.     ).  
  16.   
  17.     amount().between(new BigDecimal("10.00"), new BigDecimal("20.00"));  
  18.   
  19. ResourceCollection<Transaction> collection = gateway.transaction().search(  
  20.   
  21.     searchRequest  
  22.   
  23. );  
  24.   
  25. for (Transaction transaction : collection) {  
  26.   
  27.     System.out.println(transaction.getId());  
  28.   
  29. }  


優(yōu)勢(shì)

  • 接口提供了簡(jiǎn)單語(yǔ)法用來(lái)描述查詢(xún)條件

劣勢(shì)

  • 指定名稱(chēng)的搜索域查詢(xún)必須使用括號(hào)
  • 分步驟來(lái)查詢(xún)和構(gòu)建搜索


結(jié)語(yǔ)

一般,我們使用3中類(lèi)型的DSL實(shí)現(xiàn),接口、可讀的一行方法參數(shù)和塊。我們發(fā)現(xiàn)接口對(duì)靜態(tài)語(yǔ)言更有效,對(duì)PythonPHP,可讀行方法參數(shù)似乎最符合語(yǔ)言習(xí)慣。Ruby社區(qū)使用block作為DSL的基礎(chǔ)。

5中不同語(yǔ)言解決同一個(gè)問(wèn)題是難以置信的經(jīng)驗(yàn),雖然結(jié)果非常不同,但是我們考慮每個(gè)方法的健壯性和可讀性,以及更重要的是在這些語(yǔ)言下的使用可以幫助我們鑒別每種實(shí)現(xiàn)的優(yōu)勢(shì)與劣勢(shì)。

如果你是一個(gè)在這些語(yǔ)言中的開(kāi)發(fā)者,我們很希望聽(tīng)到你的反饋,你會(huì)用哪種語(yǔ)言如何解決這個(gè)問(wèn)題?



原文鏈接:

http://www./devblog/a-dsl-in-5-languages

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    男女午夜在线免费观看视频| 老司机激情五月天在线不卡| 国产日本欧美特黄在线观看| 国产一区欧美一区二区| 久久碰国产一区二区三区| 国产一区二区三区四区中文| 欧美成人精品一区二区久久| 国产成人精品午夜福利| 国产又粗又黄又爽又硬的| 日本黄色高清视频久久| 精品日韩国产高清毛片| 免费播放一区二区三区四区| 尹人大香蕉一级片免费看| 国产又粗又猛又黄又爽视频免费 | 精品高清美女精品国产区| 亚洲国产另类久久精品| 亚洲中文在线中文字幕91| 免费一区二区三区少妇| 成在线人免费视频一区二区| 亚洲精品福利入口在线| 欧美一区二区三区不卡高清视| 一区二区三区精品人妻| 亚洲视频在线观看你懂的| 久久大香蕉一区二区三区| 国产精品免费自拍视频| 久久国产青偷人人妻潘金莲| 亚洲一区二区福利在线| 欧美日韩国产综合在线| 人妻熟女欲求不满一区二区| 亚洲一区二区三在线播放| 欧美日韩综合在线第一页| 深夜少妇一区二区三区| 国产又黄又猛又粗又爽的片 | 少妇人妻无一区二区三区| 精品日韩国产高清毛片| 欧美精品一区久久精品| 午夜资源在线观看免费高清| 天堂网中文字幕在线观看| 午夜精品国产一区在线观看| 风韵人妻丰满熟妇老熟女av| 国产精品免费视频视频|