Java如何构造DSL方法重构

作者:??你呀不牛?? 时间:2021-10-10 02:04:09 

DSL

Domain-specific language: 一种专注于某一领域,仅针对部分表达方式的计算机编程语言。

特点

  • 方法链 Method Chaining

  • 功能序列 Functional Sequence

  • 嵌套函数 Nested Functions 嵌套函数

  • Lambda表达式/闭包 Lambda Expressions/Closures

概念有点抽象,先看代码吧

假设你想发一些邮件,你需要一个类能够方便的设置收信人、发信人、标题、内容。

一个传统的java api(具体业务代码都省略了):

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就更好了。因为用户的兴趣在于发送邮件,而不是在创建对象。

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();
}

可以做一下静态导入

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不会造就一门业务用户可以上手的语言,而会是一种业务用户也会觉得易读的语言,同时,从程序员的角度,它也会是一种阅读和编写都很直接的语言。

小结

创建DSL最好的方法是,首先将所需的API原型化,然后在基础语言的约束下将它实现。DSL的实现将会牵涉到连续不断的测试来肯定我们的开发确实瞄准了正确的方向。该“原型-测试”方法正是测试驱动开发模式(TDD-Test-Driven Development)所提倡的。

其实JDK8提供的很多api已经有很多内部DSL的语义,比如Stream流的find、count等操作都是一种DSL的语义表达,本文只是简单的说明了如何构造DSL,有机会计划找一个实际的业务代码用DSL的方式重构,敬请期待。

来源:https://juejin.cn/post/7034906507510562824

标签:Java,构造,DSL,方法,重构
0
投稿

猜你喜欢

  • Mybatis配置返回为修改影响条数方式

    2021-10-26 12:05:05
  • 详解Asp.Net MVC的Bundle捆绑

    2021-09-10 05:21:38
  • C#转换日期类型实例

    2023-07-16 21:01:19
  • Android代码检查规则Lint的自定义与应用详解

    2021-11-04 22:13:43
  • java中的interface接口实例详解

    2023-10-12 22:03:10
  • Java中Collection、List、Set、Map之间的关系总结

    2022-11-18 21:41:42
  • C# 写入XML文档三种方法详细介绍

    2021-11-08 23:20:08
  • Spring Security学习笔记(一)

    2023-09-10 06:25:09
  • Java集合类的组织结构和继承、实现关系详解

    2023-03-09 10:48:50
  • 详解Java使用JMH进行基准性能测试

    2021-08-01 12:22:32
  • 利用C#实现可以继承的"枚举"

    2021-08-08 20:55:50
  • Java Swing中JList选择事件监听器ListSelectionListener用法示例

    2021-06-21 22:52:01
  • java生成图片验证码示例程序

    2023-09-13 10:17:57
  • 使用Hibernate根据实体类自动生成表的方法

    2022-12-20 16:54:44
  • android TextView多行文本(超过3行)使用ellipsize属性无效问题的解决方法

    2021-05-28 14:02:09
  • winform中的ListBox和ComboBox绑定数据用法实例

    2023-09-24 05:02:13
  • spring mvc实现文件上传与下载功能

    2022-05-13 09:50:14
  • C/C++ 左移<<, 右移>>的作用及说明

    2021-12-30 01:42:59
  • hutool实战:IoUtil 流操作工具类(将内容写到流中)

    2022-11-16 09:17:47
  • ava实现一致性Hash算法

    2022-09-18 00:44:33
  • asp之家 软件编程 m.aspxhome.com