`
yimlin
  • 浏览: 139163 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

DSL(Domain Specific language): How to get it

阅读更多
DSL:基于规则系统组织业务规则我提出DSL,不过在该文没有太多关于DSL的东东,显得有些牵强。

先要说明一下什么是DSL(Domain Specific language),援引《产生式编程》一文:
“DSL(领域特定语言)是一种特化的,面向问题的语言。”
《产生式编程》对DSL的做如下分类:
1. 固定和独立的DSL(fixed, sparate DSL),如SQL,用独立转换器实现的,导致技术孤岛
2. 嵌入式的DSL(Embedded DSL),如类和过程,还有嵌入式的DSL
3. 模块可组合的DSL(Modularly Composable DSL),包含两种DSL:封装的DSL(encapsulated DSL)和方面性(aspectual DSL)。这个两个关系就象OOP和AOP之间的关系。
 
好了,DSL是面向问题域的。换句话说,DSL是用来解决(特定)问题
1. DSL更多的是表述特定问题域的,这是和常见编程语言的最大区别,编程语言不是面向特定的问题域的,而是一般问题域
  1.1 DSL中关于问题域的名词是关键字,而编程语言不是。
对于保险行业来说: 代理人,保单都是DSL中的关键字,而在编程语言中不是,需要建立起该对象(OO语言中)。
同时注意:OO追求的是一个细粒度的设计,而在DSL中可以是相对的一个粗粒度的概念。DSL中对象体系的观念并不直接。
  1.2 DSL不处理编程语言中所涉及到的技术问题。
 
2. DSL是针对一个问题域的过程化表述。DSL基于特定问题域的关键字——名词,给出一个特定问题的流程。
按我在《小议领域模型Domain Model》一文中的观点,Domain Object都是DSL的关键字,而DSL表述的是Domain Service所包含的流程和规则。
 
举个例子:
如果某学生的这个学期期末考成绩90分以上超过5门,那么该学生就可以获得一个小红花。
 
用DSL来描述就可能是: 
foreach students
 
if the total number of { the courses of {the student} {this term} that {it's grade > 90} } >  5  then
   the student get a red flower
 end 
if
end foreach


 而用Java程序代码(假想代码) 
Iterator studentIterator = students.iterator();
while(studentIterator.hasNext()){
    Student student 
= (Student)studentIterator.next();
    
// 从教务处获取学习成绩, 
    
// SchoolService表示教务处,"200602"是学期代号。
    CourseGrade[] grades = SchoolService.getCourseGrade(student, "200602");
    
int i = 0;
    Iterator gradeIterator 
= grades.iterator();
    
while(gradeIterator.hasNext()){
        CourseGrade courseGrade 
= (CourseGrade)gradeIterator.next();
        
if(courseGrade.getGrade() > 90){
            i
++;
        }
    }
    
if(i>5){
        
// 学校为该生记一个小红花的奖章。
        SchoolService.addMedal(student, "200602"new RedFlower());
    }
}

从上面可以看出,用DSL描述很简洁。(自己立了靶子,然后开打) 
这里我要说明的是:student和course都DSL的关键字,而在java代码中不是,是开发中建立的对象体系。
DSL中没有涉及到编程语言的技术处理问题:
1. java代码中的转型:(Student)studentIterator.next();
2. 临时变量:int i = 0;
3. 新建对象: new RedFlower()
同时:DSL中我们隐藏了一个SchoolService对象,在技术上,SchoolService教务处记录学生的成绩和奖惩,student本身不带有这些信息。
(当然关于这个例子的设计,或许有人认为student本身可以拥有这些记录,不过由于这个course还关联教师对象等,所以单独管理。BTW:例子而已表太认真嘛!)
 
通常来说Use Case描述更多是是问题域的描述。
 
这里面DSL的关键字:所谓的问题域名词(也就是我们所说的Domain Model)的设计和建立就是DSL的实现的关键,现有的手段无非就两种:
1. 工具本身内置支持Domain Object的设计和实现。这个是正统的路子。
2. 利用外置工具实现,这个有点剑走偏锋的意思。
 
常见的有以下几条路子:
一.映射法。
如Drools3推出的DSL实现方式。来看看springside的例子 
package org.springside.dsl 
  
import org.springside.bookstore.domain.Order 
import java.lang.Double 
import java.math.BigDecimal 
  
expander orderPricing.dsl 
  
rule 
" order 0.9 discount" 
    when 
       order price larger than 
100 
    then 
       
do 0.9 discount 
       #加入 
> 就可以在drl/dsl 中直接写入drl 语法 
       
>System.out.println("original price:"+order.getOriginalPrice()+" discount price:"+order.getTotalPrice()); 
end 
 
注意这个expander orderPricing.dsl将导入DSL映射: 
[when]order price larger than {topPrice}=order : Order( totalPrice >= {topPrice} ) 
[then]
do {discountRate} discount=order.setTotalPrice(new Double(new BigDecimal(order.getTotalPrice().doubleValue() * {discountRate}).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())); 
 
Oracle的Rule编辑器和JRule也属于这一类。
 
二.解析法
1. 脚本解析:
用脚本做有天然的好处,动态类型,语法的易用性等等。
出名的有Ruby:http://www.artima.com/rubycs/articles/ruby_as_dsl.html
2. 程序解析:
ajoo同学的jaskell的dsl方案:
http://forum.iteye.com/bloglist.php?userid=6423
http://forum.iteye.com/viewtopic.php?t=17579&start=120
 
或许这样分不太好,不过从本质上看,两者都通过提供相对灵活的语法解析来使代码简洁更贴近问题域描述。 
  
映射法和解析法两者都不提供Domain Model的设计支持,两者只是在代码生成手段上有所不同。 
在《DSL:基于规则系统组织业务规则》一文中所提出的组织业务规则的DSL就是指这两种。 

三.元数据生成法。
这类属于正统手法,当然也是复杂性最大的。
1. JetBrains的MPS(Meta Programming System)。
MPS的定义流程很严格
1. 首先定义基本的关键字--Struture,然后要定义其对应的editor,相当于MS VS的Designer,
2. 有了这个后就可以作为high level的模型,用来设计Model,就可以设计描述领域问题。
3. 定义low level的代码产生器,定义转换映射关系。
 
可以参照Drools的设计实现来理解MPS的工作原理:
1. 定义DSL文件的左表达式(MPS在这里还需要设计好editor,drools合二为一了)。
2. 基于这个表达式定义领域问题。
3. 定义DSL的右表达式,以便代码生成。
 
MPS采用XML结构化的节点扩展能力来实现Type的定义,可以看到其GUI工具生成的mps文件是晦涩难懂的。
 
2. Microsoft的意图编程(Intentional Programming),只在《产生式编程》中闻其大名,未见真身。
不过微软推出了VS.Net的DSL Tools,不知道是不是意图编程的成果。
http://msdn.microsoft.com/vstudio/DSLTools/
http://www.microsoft.com/downloads/details.aspx?familyid=57a14cc6-c084-48dd-b401-1845013bf834&displaylang=en
 
MS DSL的model定义也是采用XML,没有designer的帮助,也是晦涩难懂的。
不过,其模版生成采用类似ASP.NET一样的语法结构,来定义模版(Text Template)。而不是想MPS那样,在MPS和IntelliJ两个工具切换来切换去的,同时也相对容易上手。
相比而言,MPS显的庞大,VS DSL则简单明了。
这正好反应了JAVA世界和MS世界的不同,MS一向是怎么样简单就怎么来,而JAVA更多像学院派风格。  
 
准备另外写Blog详细介绍MPS和MS的DSL Tools,这是后话。
 
另:TW的taowen同学在BJUG的google groups上有过讨论,还发了一文《DSL简单观察报告》。有很好讨论,不过不好贴出来。
 
分享到:
评论

相关推荐

    java源码资源手机游戏J2ME毕业设计

    java源码资源手机游戏J2ME毕业设计提取方式是百度网盘分享地址

    第5章 存储器管理(笔记整理)

    内容概要:本章节深入探讨了存储器管理和相关概念。首先介绍了存储器的多层次结构,涵盖了寄存器、主存和辅助存储的区别及其功能。接下来讨论了主存储器、寄存器的功能和角色,包括二者如何支持程序运行及数据处理。之后分析了高速缓存和磁盘缓存的运作机制及其优化计算机性能的方式。接着概述了程序的装入、链接、地址绑定、内存保护的技术细节。此外,文章还讲述了存储器管理的高级技巧如对换技术、覆盖技术和不同的分配方式,以及各种存储管理模式的具体实施方式,比如连续分配、分页、分段及段页组合。 适用人群:对操作系统内部工作原理有一定兴趣的计算机专业学生、技术人员及爱好者。 使用场景及目标:适用于课程学习和项目实践中,帮助理解和设计复杂的存储管理系统。通过本文的学习可以达到对操作系统底层存储管理的理解,掌握不同存储分配策略的选择标准和技术应用。 阅读建议:建议逐步阅读每个小节,重点关注各部分内容的实际应用场景及其背后的设计理念。同时,尝试绘制存储层次模型和不同管理策略的工作流程图,加深理解。

    gradle611all.zip.png

    gradle611all.zip.png

    onnxruntime-1.16.0-cp39-cp39-win_amd64.whl

    onnxruntime-1.16.0-cp39-cp39-win_amd64.whl

    C#ASP.NET大型商城系统源码带数据库文档数据库 SQL2008源码类型 WebForm

    ASP.NET大型商城系统源码带数据库文档 1.开发环境:vs2010 + slq2005/2008 2.首先在SQL2005建立一个空白数据库。 3.有VS2010 打开项目,直接调试,根据出现提示建立数据库。 4.第3点出现的页面的管理员用户和密码就是后期软件的登陆帐户和密码。 5.本系统有两套模版,在店铺管理 - 页面设置 这里做修改 6.如果觉得自己的系统是空数据库,想弄成和演示的一样,那就将doc/database下面的数据库直接还原就可以了。 7.还原后的数据库登陆帐户和密码分别是:admin888 admin888

    C#ASP.NET酒店管理系统源码(WPF)数据库 Access源码类型 WinForm

    ASP.NET酒店管理系统源码(WPF) 一、源码特点 采用WPF进行开发的酒店管理系统源码,界面相当美观,功能齐全 二、菜单功能 1、预订登记:可选择入住时间、离店时间、所在城市、证件类型,保存、删除、查询、返回 2、住宿结算:新增入住、保存、删除、查询、返回 3、今日盘点:查询、返回 4、查询统计: 5、房间管理:增加房间类型、删除类型、增加房间、删除房间、保存、返回 6、用户管理:增加用户、删除用户、保存、返回 7、系统配置:基本功能 8、显示当前系统时间等功能的实现

    资源quazip.dll

    资源quazip.dll

    C#汽车货运管理系统源码 货运公司车辆管理系统源码数据库 SQL2008源码类型 WinForm

    汽车货运管理系统源码 货运公司车辆管理系统源码 货运公司管理系统采用winform C# 技术开发,数据库Sqlserver2008R2,同时兼容Mysql。 更新日志: 1.修改新增数据异常。 2.增加安装部署工程。 包括如下功能模块: 一、输入功能: 该系统提供了对基本信息录入、车辆登记录入、车辆各项费用录入、驾驶员登记录入、车辆出回车录入、主卡分卡充值录入、加油登记录入,配件信息录入等的模式录入和表格界面录入。在出现从表信息录入时会出现表格界面的录入方式其录入方式同模式录入方式一样。录入信息时可能会出现相同的信息,为避免重复录入部分字段设置了辅助录入功能,您只需输入几项即可完成录入功能。操作方便快捷,可大大提高您的工作效率。 二、查询功能: 您只需用鼠标点击一下相应节点,就可迅速查询统计销售的情况,根据不同的查询统计条件显示出需要的结果。 三、报表功能: 根据查询或者统计出来的结果生成报表。 四:打印功能: 系统支持打印功能,如想打印信息单击预览报表上的打印按钮即可。 五、安全功能: 进入系统后,单击菜单“系统→工具→用户及权限”可以设置系统的各用

    基于springboot+vue的大学生创业项目的信息管理系统源码数据库文档.zip

    基于springboot+vue的大学生创业项目的信息管理系统源码数据库文档.zip

    numpy-1.25.2-cp311-cp311-linux_armv7l.whl

    numpy-1.25.2-cp311-cp311-linux_armv7l.whl

    STM32神舟III号例程源码SD读卡器(神舟III号-库函数版)

    STM32神舟III号例程源码SD读卡器(神舟III号-库函数版)提取方式是百度网盘分享地址

    numpy-1.20.0-cp37-cp37m-linux_armv7l.whl

    numpy-1.20.0-cp37-cp37m-linux_armv7l.whl

    matplotlib-3.7.5-cp39-cp39-linux_armv7l.whl

    matplotlib-3.7.5-cp39-cp39-linux_armv7l.whl

    onnxruntime-1.16.3-cp38-cp38-win_amd64.whl

    onnxruntime-1.16.3-cp38-cp38-win_amd64.whl

    【node毕业设计】nodejs学院会议纪要管理系统源码(完整前后端+mysql+说明文档).zip

    环境说明: 开发语言:nodejs 框架:Express 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:VS code/HBuilder X

    【小程序毕业设计】自助购药小程序源码(完整前后端+mysql+说明文档+LW).zip

    功能说明: 系统主要包括首页、个人中心、用户管理、商家管理、药品信息管理、药品分类管理、发票信息管理、系统管理等功能模块。 环境说明: 开发语言:Java 服务器:tomcat7及以上 JDK版本:JDK1.8 数据库:mysql 5.7数据库工具:Navicat11及以上 开发软件:eclipse/idea 小程序框架:uniapp/原生小程序 开发工具:HBuilder X/微信开发者

    基于Servlet和JSP实现的登录Demo

    《基于Servlet和JSP实现的登录Demo》项目是一个简单的 Java Web 应用示例,展示了如何使用 Servlet 和 JSP 搭建基础的用户登录功能。项目通过 Java Servlet 处理用户请求,使用 JSP 构建前端页面,并结合 MySQL 数据库验证用户身份。用户可以通过登录页面提交账号和密码,后端接口会对用户输入进行校验,并返回登录结果。本项目适合 Java Web 初学者,旨在帮助学习 Servlet 和 JSP 的基础用法,掌握表单提交、请求转发、数据库连接等关键技术点。项目环境包括 IntelliJ IDEA、Apache Tomcat 和 MySQL,支持 JDK 8 及以上版本。

    (全新整理)中国高校各专业录取分数线、招生计划、分段表数据(2008-2023年)

    1、资源内容地址:https://blog.csdn.net/2301_79696294/article/details/143733939 2、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题 3、适用对象:大学生,本科生,研究生小白可用,容易上手!!! 4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理

    pillow-10.3.0-cp39-cp39-linux_armv7l.whl

    pillow-10.3.0-cp39-cp39-linux_armv7l.whl

    opencv_contrib_python-4.5.1.48-cp39-cp39-linux_armv7l.whl

    opencv_contrib_python-4.5.1.48-cp39-cp39-linux_armv7l.whl

Global site tag (gtag.js) - Google Analytics