Java如何構(gòu)造DSL方法重構(gòu)
DSL
Domain-specific language: 一種專注于某一領(lǐng)域,僅針對部分表達(dá)方式的計(jì)算機(jī)編程語言。
特點(diǎn)
- 方法鏈 Method Chaining
- 功能序列 Functional Sequence
- 嵌套函數(shù) Nested Functions 嵌套函數(shù)
- Lambda表達(dá)式/閉包 Lambda Expressions/Closures
概念有點(diǎn)抽象,先看代碼吧
假設(shè)你想發(fā)一些郵件,你需要一個(gè)類能夠方便的設(shè)置收信人、發(fā)信人、標(biāo)題、內(nèi)容。
一個(gè)傳統(tǒng)的java api(具體業(yè)務(wù)代碼都省略了):
public class Mailer { public void from(String fromAddress) { } public void to(String toAddress) { } public void subject(String theSubject) { } public void message(String body) { } public void send() { } }
測試要這樣寫:
public static void main(String[] args) { Mailer mailer = new Mailer(); mailer.from("build@example.com"); mailer.to("example@example.com"); mailer.subject("build notification"); mailer.message("some details about build status"); mailer.send(); }
我們可以做些重構(gòu),使這個(gè)api更流暢,更像DSL。
package dsl.example; public class Mailer { public Mailer from(String fromAddress) { return this; } public Mailer to(String toAddress) { return this; } public Mailer subject(String theSubject) { return this; } public Mailer message(String body) { return this; } public void send() { } }
這樣看起來好多了,但是如果能消除new就更好了。因?yàn)橛脩舻呐d趣在于發(fā)送郵件,而不是在創(chuàng)建對象。
public static void main(String[] args) { new Mailer() .from("build@example.com") .to("example@example.com") .subject("build notification") .message("some details about build status") .send(); }
測試:
public static void main(String[] args) { Mailer.mail() .from("build@example.com") .to("example@example.com") .subject("build notification") .message("some details about build status") .send(); }
可以做一下靜態(tài)導(dǎo)入
public static void main(String[] args) { import static dsl.example.Mailer.mail;mail() .from("build@example.com") .to("example@example.com") .subject("build notification") .message("some details about build status") .send(); }
這樣,一個(gè)DSL的語句就完成了。一般來說,使用Java編寫的DSL不會造就一門業(yè)務(wù)用戶可以上手的語言,而會是一種業(yè)務(wù)用戶也會覺得易讀的語言,同時(shí),從程序員的角度,它也會是一種閱讀和編寫都很直接的語言。
小結(jié)
創(chuàng)建DSL最好的方法是,首先將所需的API原型化,然后在基礎(chǔ)語言的約束下將它實(shí)現(xiàn)。DSL的實(shí)現(xiàn)將會牽涉到連續(xù)不斷的測試來肯定我們的開發(fā)確實(shí)瞄準(zhǔn)了正確的方向。該“原型-測試”方法正是測試驅(qū)動開發(fā)模式(TDD-Test-Driven Development)所提倡的。
其實(shí)JDK8提供的很多api已經(jīng)有很多內(nèi)部DSL的語義,比如Stream流的find、count等操作都是一種DSL的語義表達(dá),本文只是簡單的說明了如何構(gòu)造DSL,有機(jī)會計(jì)劃找一個(gè)實(shí)際的業(yè)務(wù)代碼用DSL的方式重構(gòu),敬請期待。
相關(guān)文章
Map映射LinkedHashSet與LinkedHashMap應(yīng)用解析
這篇文章主要為大家介紹了Map映射LinkedHashSet與LinkedHashMap的應(yīng)用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步2022-03-03Java 基礎(chǔ)之內(nèi)部類詳解及實(shí)例
這篇文章主要介紹了 Java 基礎(chǔ)之內(nèi)部類詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03一文帶你看懂Android動畫的實(shí)現(xiàn)原理
動畫是 Android 應(yīng)用程序中重要的交互特性,ndroid 提供了多種動畫效果,包括平移、縮放、旋轉(zhuǎn)和透明度等,它們可以通過代碼或 XML 來實(shí)現(xiàn),本文將介紹 Android 動畫的原理和實(shí)現(xiàn)方法,并提供一些示例,需要的朋友可以參考下2023-07-07java實(shí)現(xiàn)微信支付結(jié)果通知
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信支付結(jié)果通知,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01