Java如何構造DSL方法重構
DSL
Domain-specific language: 一種專注于某一領域,僅針對部分表達方式的計算機編程語言。
特點
- 方法鏈 Method Chaining
- 功能序列 Functional Sequence
- 嵌套函數 Nested Functions 嵌套函數
- Lambda表達式/閉包 Lambda Expressions/Closures
概念有點抽象,先看代碼吧
假設你想發(fā)一些郵件,你需要一個類能夠方便的設置收信人、發(fā)信人、標題、內容。
一個傳統(tǒng)的java api(具體業(yè)務代碼都省略了):
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();
}我們可以做些重構,使這個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就更好了。因為用戶的興趣在于發(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)導入
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();
}這樣,一個DSL的語句就完成了。一般來說,使用Java編寫的DSL不會造就一門業(yè)務用戶可以上手的語言,而會是一種業(yè)務用戶也會覺得易讀的語言,同時,從程序員的角度,它也會是一種閱讀和編寫都很直接的語言。
小結
創(chuàng)建DSL最好的方法是,首先將所需的API原型化,然后在基礎語言的約束下將它實現。DSL的實現將會牽涉到連續(xù)不斷的測試來肯定我們的開發(fā)確實瞄準了正確的方向。該“原型-測試”方法正是測試驅動開發(fā)模式(TDD-Test-Driven Development)所提倡的。
其實JDK8提供的很多api已經有很多內部DSL的語義,比如Stream流的find、count等操作都是一種DSL的語義表達,本文只是簡單的說明了如何構造DSL,有機會計劃找一個實際的業(yè)務代碼用DSL的方式重構,敬請期待。
相關文章
Map映射LinkedHashSet與LinkedHashMap應用解析
這篇文章主要為大家介紹了Map映射LinkedHashSet與LinkedHashMap的應用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進步2022-03-03

