Java如何構(gòu)造DSL方法重構(gòu)
DSL
Domain-specific language: 一種專(zhuān)注于某一領(lǐng)域,僅針對(duì)部分表達(dá)方式的計(jì)算機(jī)編程語(yǔ)言。
特點(diǎn)
- 方法鏈 Method Chaining
- 功能序列 Functional Sequence
- 嵌套函數(shù) Nested Functions 嵌套函數(shù)
- Lambda表達(dá)式/閉包 Lambda Expressions/Closures
概念有點(diǎn)抽象,先看代碼吧
假設(shè)你想發(fā)一些郵件,你需要一個(gè)類(lèi)能夠方便的設(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() {
}
}測(cè)試要這樣寫(xiě):
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() {
}
}這樣看起來(lái)好多了,但是如果能消除new就更好了。因?yàn)橛脩?hù)的興趣在于發(fā)送郵件,而不是在創(chuàng)建對(duì)象。
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();
}測(cè)試:
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的語(yǔ)句就完成了。一般來(lái)說(shuō),使用Java編寫(xiě)的DSL不會(huì)造就一門(mén)業(yè)務(wù)用戶(hù)可以上手的語(yǔ)言,而會(huì)是一種業(yè)務(wù)用戶(hù)也會(huì)覺(jué)得易讀的語(yǔ)言,同時(shí),從程序員的角度,它也會(huì)是一種閱讀和編寫(xiě)都很直接的語(yǔ)言。
小結(jié)
創(chuàng)建DSL最好的方法是,首先將所需的API原型化,然后在基礎(chǔ)語(yǔ)言的約束下將它實(shí)現(xiàn)。DSL的實(shí)現(xiàn)將會(huì)牽涉到連續(xù)不斷的測(cè)試來(lái)肯定我們的開(kāi)發(fā)確實(shí)瞄準(zhǔn)了正確的方向。該“原型-測(cè)試”方法正是測(cè)試驅(qū)動(dòng)開(kāi)發(fā)模式(TDD-Test-Driven Development)所提倡的。
其實(shí)JDK8提供的很多api已經(jīng)有很多內(nèi)部DSL的語(yǔ)義,比如Stream流的find、count等操作都是一種DSL的語(yǔ)義表達(dá),本文只是簡(jiǎn)單的說(shuō)明了如何構(gòu)造DSL,有機(jī)會(huì)計(jì)劃找一個(gè)實(shí)際的業(yè)務(wù)代碼用DSL的方式重構(gòu),敬請(qǐng)期待。
相關(guān)文章
java web實(shí)現(xiàn)簡(jiǎn)單留言板功能
這篇文章主要為大家詳細(xì)介紹了java web實(shí)現(xiàn)簡(jiǎn)單留言板功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
logback FixedWindowRollingPolicy固定窗口算法重命名文件滾動(dòng)策略
這篇文章主要介紹了FixedWindowRollingPolicy根據(jù)logback 固定窗口算法重命名文件滾動(dòng)策略源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)主流定時(shí)任務(wù)解決方案全橫評(píng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
淺談java中BigDecimal類(lèi)的簡(jiǎn)單用法
這篇文章主要介紹了淺談java中BigDecimal類(lèi)的簡(jiǎn)單用法,在開(kāi)發(fā)時(shí),如果我們需要精確計(jì)算的結(jié)果,必須使用BigDecimal類(lèi)來(lái)操作。感興趣的話可以了解一下2020-07-07
Springboot集成graylog及配置過(guò)程解析
這篇文章主要介紹了Springboot集成graylog及配置過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12

