频 道 直 达 - 新闻 - 读书 - 培训 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 技术圈 - 博客 - BBS
51CTO.COM_中国领先的IT技术网站
找资料:

使用Java实现内部领域特定语言(1)

作者: Alex Ruiz and Jeff Bay/沙晓兰 编译 出处:InfoQ中文站 2008-03-20 13:48    砖    好    评论   进入论坛
阅读提示:领域特定语言(DSL)通常被定义为一种特别针对某类特殊问题的计算机语言,它不打算解决其领域外的问题。本文将描述怎样使用Java语言来编写领域特定语言,并将建议一些组建DSL语言时可采用的模式。

简介
 
领域特定语言(DSL)通常被定义为一种特别针对某类特殊问题的计算机语言,它不打算解决其领域外的问题。对于DSL的正式研究已经持续很多年,直到最近,在程序员试图采用最易读并且简炼的方法来解决他们的问题的时候,内部DSL意外地被写入程序中。近来,随着关于Ruby和其他一些动态语言的出现,程序员对DSL的兴趣越来越浓。这些结构松散的语言给DSL提供某种方法,使得DSL允许最少的语法以及对某种特殊语言最直接的表现。但是,放弃编译器和使用类似Eclipse这样最强大的现代集成开发环境无疑是该方式的一大缺点。然而,作者终于成功地找到了这两个方法的折衷解决方式,并且,他们将证明该折衷方法不但可能,而且对于使用Java这样的结构性语言从面向DSL的方式来设计API很有帮助。本文将描述怎样使用Java语言来编写领域特定语言,并将建议一些组建DSL语言时可采用的模式。
 
Java适合用来创建内部领域特定语言吗?
 
在我们审视Java语言是否可以作为创建DSL的工具之前,我们首先需要引进“内部DSL”这个概念。一个内部DSL在由应用软件的主编程语言创建,对定制编译器和解析器的创建(和维护)都没有任何要求。Martin Fowler曾编写过大量各种类型的DSL,无论是内部的还是外部的,每种类型他都编写过一些不错的例子。但使用像Java这样的语言来创建DSL,他却仅仅一笔带过。
 
另外还要着重提出的很重要的一点是,在DSL和API两者间其实很难区分。在内部DSL的例子中,他们本质上几乎是一样的。在联想到DSL这个词汇的时候,我们其实是在利用主编程语言在有限的范围内创建易读的API。“内部DSL”几乎是一个特定领域内针对特定问题而创建的极具可读性的API的代名词。
 
任何内部DSL都受它基础语言的文法结构的限制。比如在使用Java的情况下,大括弧,小括弧和分号的使用是必须的,并且缺少闭包和元编程有可能会导致DSL比使用动态语言创建来的更冗长。
 
但从光明的一面来看,通过使用Java,我们同时能利用强大且成熟的类似于Eclipse和IntelliJ IDEA的集成开发环境,由于这些集成开发环境“自动完成(auto-complete)”、自动重构和debug等特性,使得DSL的创建、使用和维护来的更加简单。另外,Java5中的一些新特性(比如generic、varargs 和static imports)可以帮助我们创建比以往任何版本任何语言都简洁的API。
 
一般来说,使用Java编写的DSL不会造就一门业务用户可以上手的语言,而会是一种业务用户也会觉得易读的语言,同时,从程序员的角度,它也会是一种阅读和编写都很直接的语言。和外部DSL或由动态语言编写的DSL相比有优势,那就是编译器可以增强纠错能力并标识不合适的使用,而Ruby或Pearl会“愉快接受”荒谬的input并在运行时失败。这可以大大减少冗长的测试,并极大地提高应用程序的质量。然而,以这样的方式利用编译器来提高质量是一门艺术,目前,很多程序员都在为尽力满足编译器而非利用它来创建一种使用语法来增强语义的语言。
利用Java来创建DSL有利有弊。最终,你的业务需求和你所工作的环境将决定这个选择正确与否。
 
将Java作为内部DSL的平台

动态构建SQL是一个很好的例子,其建造了一个DSL以适合SQL领域,获得了引人注意的优势。
传统的使用SQL的Java代码一般类似于:
 
String sql = "select id, name " +
"from customers c, order o " +
"where " +
"c.since >= sysdate - 30 and " +
"sum(o.total) > " + significantTotal + " and " +
"c.id = o.customer_id and " +
"nvl(c.status, 'DROPPED') != 'DROPPED'";
 
从作者最近工作的系统中摘录的另一个表达方式是:
 
Table c = CUSTOMER.alias();
Table o = ORDER.alias();
Clause recent = c.SINCE.laterThan(daysEarlier(30));
Clause hasSignificantOrders = o.TOTAT.sum().isAbove(significantTotal);
Clause ordersMatch = c.ID.matches(o.CUSTOMER_ID);
Clause activeCustomer = c.STATUS.isNotNullOr("DROPPED");
String sql = CUSTOMERS.where(recent.and(hasSignificantOrders)
.and(ordersMatch)
.and(activeCustomer)
.select(c.ID, c.NAME)
.sql();
 
这个DSL版本有几项优点。后者能够透明地适应转换到使用PreparedStatement的方法——用String拼写SQL的版本则需要大量的修改才能适应转换到使用捆绑变量的方法。如果引用不正确或者一个integer变量被传递到date column作比较的话,后者版本根本无法通过编译。代码“nvl(foo, 'X') != 'X'”是Oracle SQL中的一种特殊形式,这个句型对于非Oracle SQL程序员或不熟悉SQL的人来说很难读懂。例如在SQL Server方言中,该代码应该这样表达“(foo is null or foo != 'X')”。但通过使用更易理解、更像人类语言的“isNotNullOr(rejectedValue)”来替代这段代码的话,显然会更具阅读性,并且系统也能够受到保护,从而避免将来为了利用另一个数据库供应商的设施而不得不修改最初的代码实现。
 
使用Java创建内部DSL

创建DSL最好的方法是,首先将所需的API原型化,然后在基础语言的约束下将它实现。DSL的实现将会牵涉到连续不断的测试来肯定我们的开发确实瞄准了正确的方向。该“原型-测试”方法正是测试驱动开发模式(TDD-Test-Driven Development)所提倡的。
 
在使用Java来创建DSL的时候,我们可能想通过一个连贯接口(fluent interface)来创建DSL。连贯接口可以对我们所想要建模的领域问题提供一个简介但易读的表示。连贯接口的实现采用方法链接(method chaining)。但有一点很重要,方法链接本身不足以创建DSL。一个很好的例子是Java的StringBuilder,它的方法“append”总是返回一个同样的StringBuilder的实例。这里有一个例子:
 
StringBuilder b = new StringBuilder();
b.append("Hello. My name is ")
.append(name)
.append(" and my age is ")
.append(age);
 
该范例并不解决任何领域特定问题。
 

共6页: 1 [2] [3] [4] [5] [6] 下一页
【内容导航】
关于 Java  DSL
专题
运营商封堵非法ADSL共享
Java实用开发全集
Java类的基础教程专题
Java发展动态专题
ADSL2+离我们越来越近
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 领 先 的 IT 技 术 网 站 ·
技 术 成 就 梦 想
·Java基础教程 (查看70832次)
·UML类图详解 (查看64231次)
·UML统一建模语言 (查看34958次)
·C#技术开发指南 (查看33510次)
·C++是垃圾语言?! (查看31761次)
·Java编程开发手册 (1196个砖)
·Java基础教程 (429个砖)
·C#技术开发指南 (309个砖)
·.NET开发手册 (240个砖)
·PB开发教程 (223个砖)
·Java编程开发手册 (654个好)
·Java基础教程 (574个好)
·.NET开发手册 (271个好)
·PB开发教程 (212个好)
·Delphi开发技术手册 (190个好)
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。