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简单观察报告》。有很好讨论,不过不好贴出来。
 
Calpuff模型实战:从气象数据预处理到污染物扩散模拟全流程指南 本文提供了一份详尽的Calpuff模型实战指南,涵盖从气象数据预处理、地形处理到污染物扩散模拟与结果可视化的全流程。重点解析了Calmet气象场构建、Calpuff核心参数配置,并与AERMOD模型进行对比,帮助环境工程师与科研人员掌握这一强大的三维非稳态拉格朗日扩散模型,以应对复杂地形、海岸熏烟等实际模拟挑战。 阅读详情

相关推荐

Clion编译stm32cube初始化工程时non constant or forward reference address expression for section .ARM.extab报错

相信应该有同学在看了稚晖君关于clion开发stm32的文章之后也想在自己PC上实现“优雅の嵌入式开发”遇到和我类似的问题。他的文章是22年写的,我个人猜测应当是版本更新导致的不适配。意思就是说 READONLY 只能在gcc11以后的版本中使用,gcc10及以前的版本将无法正确识别,也就有如下错误。或者就可以将gcc升级至最新的版本。记得在clion工具链中修改c,cpp编译器的位置。可以将文本括号中的 READONLY 全部删除。当时由于没有注意到这行注释导致在这里卡了好久。

2301_77256849的博客 2512

【日常记录:商品检索服务】java实现封装DSL语句

以下是继续从BoolQueryBuilder调用must方法,再从must方法里边调用QueryBuilders.matchQuery这样就完成了第一个。是上篇文章根据业务分析锁封装的前端的查询条件,最终将es的检索和聚合条件封装完了之后再返回。然后再从bool里继续嵌套,只要用到es中的检索方法就使用QueryBuilders来调用。前一篇已经根据业务分析了es的查询结构,这篇就开始用java操作es进行封装。总体思路还是对照着所构建好的DSL查询语句,一一对应进行封装。最终将构建好的条件全部拿过来。..

qq_17593727的博客 1198

Latex下使用JabRef添加参考文献

文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 前言 Latex可以手动添加参考文献,但文献过多时,使用JabRef软件相对方便。 提示:以下是本篇文章正文内容,下面案例可供参考 一、JabRef安装 网址:http://www.jabref.org 打开网址后,点击“Download” 进入如下页面后,选择 portable (便携版,无需安装),下载后是一压缩包,打开即可使用。 二、使用 1.创建库 ...

sz3076799的博客 3467

DSL 领域特定语言

一、DSL介绍 DSL(Domain Specific Language)是针对某一领域,具有受限表达性的一种计算机程序设计语言。 常用于聚焦指定的领域或问题,这就要求 DSL 具备强大的表现力,同时在使用起来要简单。说到DSL,大家也会自然的想到通用语言(如Java、C等)。 为什么没有一种语言同时 兼具『简洁』和『业务表达』能力呢? 从信息论本质上来讨论这个问题,每个语言的程序都可以抽象为一个字符串,每个字符串由有限数量的合法字符组成,它在运行时会实现某个功能,因而可以看作是一种需求的信源编码。每

Sunny的专栏 3万+

ubuntu打实时内核补丁教程以及安装后显卡驱动问题解决方法

在ubuntu20.04上安装成功,亲测有效 目录ubuntu打实时内核补丁教程1、下载实时内核2、解压和打补丁(patch)3、安装依赖和编译安装4、修改一些文件,便于之后切换内核5、重启电脑实时内核版本下安装nvidia显卡驱动的问题1、先切换回之前的内核(非实时)版本2、重装之前内核(非实时)版本下的显卡驱动3、切换回实时内核(按照上面的步骤)4、在实时内核下安装显卡驱动 ubuntu打实时内核补丁教程 安装目标系统:ubuntu20.04 电脑配置:i9,2080ti 1、下载实时内核 打开终端,输

weixin_39275295的博客 7996

将外部电磁近场数据导入 ANSYS HFSS

本博客介绍了如何将电磁近场数据导入 ANSYS HFSS。用户可能需要导入字段,无论是通过分析计算、测量、由其他工具生成还是从提供商处接收的字段,并将其用作实际激励来执行不同类型的分析。以下是导入过程的简要概述,视频链接中提供了完整的演示。为了定义简单基元近场源,HFSS 使用两种外部数据文件。首先,实际位置/字段数据以 .nfd 格式存储。其次,Ansys Near field Descriptor 文件(.and 文件)存储 .nfd 数据的一般几何信息和路径。

jkh920184196的博客 2327

走近“领域特定语言”(Domain-Specific Languages)

领域特定语言(Domain-Specific Languages,简称DSL),是一个很有用的术语和概念,但其边界很模糊。一些东西很明显是DSL,但另一些可能会引发争议。本文接下来就走近“领域特定语言”,了解它的概念、为何要采用DSL,以及使用时应该注意的问题。 1.定义DSL 领域特定语言(名词),针对某一特定领域,具有受限表达性的一种计算机程序设计语言。这一定义包含4个关键元素: 计算机...

华章IT官方博客 1676

PTA 学生信息的那些操作:添加记录(结构体)

这是河南工业大学自主命题的一道基础题,题目如下: 有一学生成绩表,包括学号、姓名、3门课程成绩。已知该成绩表按学号升序排序。请编程实现,添加一个新的学生信息,且使成绩表仍按学号有序;若待添加的学号与已有学号重复,则输出错误信息,拒绝添加。 输入格式: 首先输入一个整数n(1<=n<=100),表示学生人数; 然后输入n行,每行包含一个学生的信息:学号(12位)、姓名(不含空格且不超过20位),以及3个整数,表示3门课成绩,数据之间用空格隔开。 最后一行输入一个待添加的学生信息,包括学号

weixin_63617665的博客 3156

ElasticSearch的Mapping和DSL语言

DSL,elaticSearch,mapping,映射

aoxiaojun的博客 859

基于STM32L4XX 、HAL库的TMP144YFFR数字温度传感器驱动应用C语言程序设计

define TMP144_ADDRESS 0x00 // 默认为全局地址,用于单器件或MDA命令。#define TMP144_CMD_READ_TEMP 0x00 // 读取温度寄存器命令。if (temp_raw & 0x800) { // 判断第11位(符号位)

PP_Cottage的博客 91

手把手教你ensp仿真搭建校园网(含防火墙及无线网络)系列(二)校园网接入层交换机配置

本系列博客将带你从零开始,使用 华为 eNSP(Enterprise Network Simulation Platform) 仿真搭建一个完整的校园网络,涵盖 核心层、汇聚层、接入层、防火墙安全策略、无线AC+AP组网 等实战场景。无论你是网络初学者还是希望深化实战经验的工程师,都能通过本教程掌握企业级网络的规划、配置与排错技巧。

echo的博客 1219

MDSF:DSL(Domain Specific Language)介绍

前面介绍过模型驱动开发(MDD)、软件工厂(Software factory)、特定领域建模 DSM(Domain Specific)等都是高抽象的开发方法,这些方法使用的语言都是特定领域语言(DSL)。相比于通用目的语言(C#/C++/JAVA/Delphi等)而言,DSL是一种为了特定任务而设计的开发语言,例如SQL是一种专门处理数据库的语言,本篇将介绍一下DSL。 一种语言   我们熟知...

weixin_34289744的博客 467

LVGL core theme主题管理(lv_theme.c)

如果打开宏,主题的初始化是在显示设备注册时完成的。整个themes的实现放在目录下面。这里一共有三套主题(basic、default和mono)可供选择或者参考。源码中默认对接的是 default 主题,所以在中,看到的是调用default主题的接口。也就是说,如果需要更换主题,把这里面的接口换掉就可以了。或者要重新做一套主题,参考这些实现修改也就可以了。虽说有三套主题,但逻辑流程是一样的。主要完成两个工作:构造lv_theme_t结构体和初始化默认样多备用(style_init函数内实现)。构造。....

Bigan(安)的博客 3411

ElasticSearch-Query DSL(Domain Specific Language)

elasticsearch

抽象的螺旋 1362

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

DSL搜索 - 入门语法

目录请求参数的查询(QueryString)DSL基本语法搜索不合法问题定位 请求参数的查询(QueryString) 查询[字段]包含[内容]的文档 GET /shop/_doc/_search?q=desc:慕课网 GET /shop/_doc/_search?q=nickname:慕&q=age:25 text与keyword搜索对比测试(keyword不会被倒排索...

柏~的博客 447

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Elasticsearch DSL(Domain Specific Language)基本语法

Elasticsearch(ES)的查询语法(DSL)是其核心功能,基于JSON格式实现灵活的数据检索与分析。

qq_44174090的博客 335

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Query DSL(Domain Specific Language)

概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值。:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值。使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。因为filter不计算评分,所以性能更高,可以先根据filter筛出部分数据,再进行其他条件的筛选。排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前。

weixin_41063119的博客 155

常用DSL语句

常用DSL语句 查看所有索引 GET /_cat/indices?v 删除某个索引 DELETE /skuinfo 新增索引 PUT /user 创建映射 PUT /user/userinfo/_mapping { "properties": { "name": { "type": "text", "analy...

cs950809的博客 3048

ES DSL、特性、索引、基概、进阶

文章目录elasticsearch1 特点1.1 天然分片,天然集群1.2 天然索引1.3 lucene倒排索引结构2 基概3 状态介绍3.1 状态13.2 状态24 es中的DSL4.1 数据结构4.2 增加操作4.3 更新操作4.4 删除索引4.5 查询操作4.6 分页查询4.7 聚合 elasticsearch 1 特点 1.1 天然分片,天然集群 实则es是把这个数据分为多个碎片分布式的放在各个节点上,随着数据的增加会将其增加节点数,将多个分片放在多个节点上,以此达

友培的博客 2140

ElasticSearch DSL 领域专用语言

博文目录 文章目录ElasticSearch DSL(Domain Specific Language) 领域专用语言Query DSLFilter DSL区别查询无查询条件有查询条件叶子查询(单条件)模糊匹配matchmatch 的底层转换multi_matchmatch_phrasematch phrase 原理 - term positionmatch phrase搜索参数 - slopquery_string前缀搜索 prefix通配符搜索 wildcard正则搜索搜索推荐模糊搜索技术 fuzzy总

mrathena 487

DSL语法实例

API的基本用法: GET /user/_doc/_search { "query": { "match_all": {} }, "from": 0, "size": 100 } 查找 GET /user/_doc/_search { "query":{ "bool":{ "must":{ "term":{"tag":"好"} } } } } 更新或添加文档 PUT /user/_doc/张三 { "usern...

junqing124的专栏 812

ElasticSearch中DSL高级检索(Query)

ES官方提供了两中检索方式:一种是通过 URL 参数进行搜索,另一种是通过 DSL(Domain Specified Language) 进行搜索。官方更推荐使用第二种方式第二种方式是基于传递JSON作为请求体(request body)格式与ES进行交互,这种方式更强大,更简洁。

程序员小王的博客 2507

Elastic Stack核心技术实战02--Elasticsearch中的Domain Specific Language详解

上一篇博客中给大家介绍了Elasticsearch单机版的环境搭建以及简单的增删改查,今天我们就来学习一下Elasticsearch的Domain Specific Language,也就是我们常说的DSL查询。在es中以JSON的格式出现。 在此之前先给大家介绍一下分词器,首先 ...

代码洁癖症患者 618

用写sql的思路写 Elasticsearch 的DSL

目录Elasticsearch的DSL基础操作基础查询筛选查询多条件教材筛选聚合查询排序对结果分页查询kibana可视化图表配置 先挖坑,慢慢填 Elasticsearch的DSL 基础操作 GET POST DELETE PUT HEAD 基础查询 筛选查询 多条件教材筛选 聚合查询 排序 对结果分页查询 kibana可视化图表配置 (这个可以单开一个的吧) ...

Neon Light 的博客 266

dsl mysql_ES中查询语句DSL(domain specific language)

#查看所有索引GET/_cat/indices?v#删除某个索引DELETE/skuinfo#新增索引PUT/user#创建映射PUT/user/userinfo/_mapping{"properties": {"name":{"type": "text","analyzer": "ik_smart","search_analyzer": "ik_smart","store": false},"c...

weixin_39653481的博客 217

Java-ES-DSL操作-查询

查询所有以cust开头的索引 GET /cust*/_search?pretty 返回bank索引中的所有的文档: GET /bank/_search?q=*&pretty 等同于: POST /bank/_search?pretty { "query": {"match_all": {}} } 指定返回第11到第20个文档,并指定返回字段: POST /bank/_sear...

fayxjc的博客 2537
上一篇: 写在Tapestry 升级成为Apache一级项目之时
下一篇: DSL(Domain Specific language): How to get it
林仪明
博客等级 码龄25年 313粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值