教育房产时事环球科技商业
投稿投诉
商业财经
热点动态
科技数码
软件应用
国际环球
晨报科学
新闻时事
信息智能
汽车房产
办公手机
教育体育
生活生物

dsl是什么意思啊(dsl口是什么意思啊)

  最近在一个项目中,因为涉及很多状态的流转,我们选择使用状态机引擎来表达状态流转。因为状态机DSL(Domain Specific Languages)带来的表达能力,相比较于if-else的代码,要更优雅更容易理解。另一方面,状态机很简单,不像流程引擎那么华而不实。
  一开始我们选用了一个开源的状态机引擎,但我觉得不好用,就自己写了一个能满足我们要求的简洁版状态机,这样比较KISS(Keep It Simple and Stupid)。
  作为COLA开源的一部分,我已经将该状态机(cola-statemachine)开源,你可以访问https://github.com/alibaba/COLA获取。
  在实现状态机的过程中,有幸看到Martin Fowler写的《Domain Specific Languages》。书中的内容让我对DSL有了不一样的认知。
  这也是为什么会有这边文章的原因,希望你看完这边文章以后,可以对什么是DSL、如何使用DSL、如何使用状态机都能有一个不一样的体会。DSL
  在介绍如何实现状态机之前,不妨让我们先来看一下什么是DSL,在Martin Fowler的《Domain Specific Languages》书中。开篇就是以State Machine来作为引子介绍DSL的。有时间的话,强烈建议你去读读这本书。没时间的话,看看下面的内容也能掌握个大概了。
  下面就让我提炼一下书中的内容,带大家深入了解下DSL。什么是DSL
  DSL是一种工具,它的核心价值在于,它提供了一种手段,可以更加清晰地就系统某部分的意图进行沟通。
  这种清晰并非只是审美追求。一段代码越容易看懂,就越容易发现错误,也就越容易对系统进行修改。因此,我们鼓励变量名要有意义,文档要写清楚,代码结构要写清晰。基于同样的理由,我们应该也鼓励采用DSL。
  按照定义来说,DSL是针对某一特定领域,具有受限表达性的一种计算机程序设计语言。这一定义包含3个关键元素:语言性(language nature):DSL是一种程序设计语言,因此它必须具备连贯的表达能力——不管是一个表达式还是多个表达式组合在一起。受限的表达性(limited expressiveness):通用程序设计语言提供广泛的能力:支持各种数据、控制,以及抽象结构。这些能力很有用,但也会让语言难于学习和使用。DSL只支持特定领域所需要特性的最小集。使用DSL,无法构建一个完整的系统,相反,却可以解决系统某一方面的问题。针对领域(domain focus):只有在一个明确的小领域下,这种能力有限的语言才会有用。这个领域才使得这种语言值得使用。
  比如正则表达式, /\d{3}-\d{3}-\d{4}/就是一个典型的DSL,解决的是字符串匹配这个特定领域的问题。DSL的分类
  按照类型,DSL可以分为三类:内部DSL(Internal DSL)、外部DSL(External DSL)、以及语言工作台(Language Workbench)。Internal DSL是一种通用语言的特定用法。用内部DSL写成的脚本是一段合法的程序,但是它具有特定的风格,而且只用到了语言的一部分特性,用于处理整个系统一个小方面的问题。 用这种DSL写出的程序有一种自定义语言的风格,与其所使用的宿主语言有所区别。例如我们的状态机就是Internal DSL,它不支持脚本配置,使用的时候还是Java语言,但并不妨碍它也是DSL。     builder.externalTransition()                .from(States.STATE1)                .to(States.STATE2)                .on(Events.EVENT1)                .when(checkCondition())                .perform(doAction());External DSL是一种"不同于应用系统主要使用语言"的语言。外部DSL通常采用自定义语法,不过选择其他语言的语法也很常见(XML就是一个常见选 择)。比如像Struts和Hibernate这样的系统所使用的XML配置文件。Workbench是一个专用的IDE,简单点说,工作台是DSL的产品化和可视化形态。
  三个类别DSL从前往后是有一种递进关系,Internal DSL最简单,实现成本也低,但是不支持"外部配置"。Workbench不仅实现了配置化,还实现了可视化,但是实现成本也最高。他们的关系如下图所示:
  不同DSL该如何选择
  几种DSL类型各有各的使用场景,选择的时候,可以这样去做一个判断。Internal DSL:假如你只是为了增加代码的可理解性,不需要做外部配置,我建议使用Internal DSL,简单、方便、直观。External DSL:如果你需要在Runtime的时候进行配置,或者配置完,不想重新部署代码,可以考虑这种方式。比如,你有一个规则引擎,希望增加一条规则的时候,不需要重复发布代码,那么可以考虑External。Workbench:配置也好,DSL Script也好,这东西对用户不够友好。比如在淘宝,各种针对商品的活动和管控规则非常复杂,变化也快。我们需要一个给运营提供一个workbench,让他们自己设置各种规则,并及时生效。这时的workbench将会非常有用。
  总而言之,在合适的地方用合适的解决方案,不能一招鲜吃遍天。就像最臭名昭著的DSL——流程引擎,就属于那种严重的被滥用和过渡设计的典型,是把简单的问题复杂化的典型。
  最好不要无端增加复杂性。然而,想做简单也不是一件容易的事,特别是在大公司,我们不仅要写代码,还要能沉淀"NB的技术",最好是那种可以把老板说的一愣一愣的技术,就像尼古拉斯在《反脆弱》里面说的:
  在现代生活中,简单的做法一直难以实现,因为它有违某些努力寻求复杂化以证明其工作合理性的人所秉持的精神。Fluent Interfaces
  在编写软件库的时候,我们有两种选择。一种是提供Command-Query API,另一种是Fluent Interfaces。比如Mockito的API when(mockedList.get(anyInt())).thenReturn("element")就是一种典型连贯接口的用法。
  连贯接口(fluent interfaces)是实现Internal DSL的重要方式,为什么这么说呢?
  因为Fluent的这种连贯性带来的可读性和可理解的提升,其本质不仅仅是在提供API,更是一种领域语言,是一种Internal DSL。
  比如Mockito的API when(mockedList.get(anyInt())).thenReturn("element")就非常适合用Fluent的形式,实际上,它也是单元测试这个特定领域的DSL。
  如果把这个Fluent换成是Command-Query API,将很难表达出测试框架的领域。String element = mockedList.get(anyInt());boolean isExpected = "element".equals(element);
  这里需要注意的是,连贯接口不仅仅可以提供类似于method chaining和builder模式的方法级联调用,比如OkHttpClient中的BuilderOkHttpClient.Builder builder=new OkHttpClient.Builder();        OkHttpClient okHttpClient=builder                .readTimeout(5*1000, TimeUnit.SECONDS)                .writeTimeout(5*1000, TimeUnit.SECONDS)                .connectTimeout(5*1000, TimeUnit.SECONDS)                .build();
  他更重要的作用是,限定方法调用的顺序。比如,在构建状态机的时候,我们只有在调用了from方法后,才能调用to方法,Builder模式没有这个功能。
  怎么做呢?我们可以使用Builder和Fluent接口结合起来的方式来实现,下面的状态机实现部分,我会进一步介绍。状态机
  好的,关于DSL的知识我就介绍这么多。接下来,让我们看看应该如何实现一个Internal DSL的状态机引擎。状态机选型
  我反对滥用流程引擎,但并不排斥状态机,主要有以下两个原因:首先,状态机的实现可以非常的轻量,最简单的状态机用一个Enum就能实现,基本是零成本。其次,使用状态机的DSL来表达状态的流转,语义会更加清晰,会增强代码的可读性和可维护性。
  然而,我们的业务场景虽然也不是特别复杂,但还是超出了Enum仅支持线性状态流转的范畴。因此不得不先向外看看。开源状态机太复杂
  和流程引擎一样,开源的状态机引擎不可谓不多,我着重看了两个状态机引擎的实现,一个是Spring Statemachine,一个是Squirrel statemachine。这是目前在github上的Top 2 状态机实现,他们的优点是功能很完备,缺点也是功能很完备。
  当然,这也不能怪开源软件的作者,你好不容易开源一个项目,至少要把UML State Machine上罗列的功能点都支持掉吧。
  就我们的项目而言(其实大部分项目都是如此)。我实在不需要那么多状态机的高级玩法:比如状态的嵌套(substate),状态的并行(parallel,fork,join)、子状态机等等。开源状态机性能差
  除此之外,还有一个我不能容忍的问题是,这些开源的状态机都是有状态的(Stateful)的,表面上来看,状态机理所当然是应该维持状态的。但是深入想一下,这种状态性并不是必须的,因为有状态,状态机的实例就不是线程安全的,而我们的应用服务器是分布式多线程的,所以在每一次状态机在接受请求的时候,都不得不重新build一个新的状态机实例。
  以电商交易为例,用户下单后,我们调用状态机实例将状态改为"Order Placed"。当用户支付订单的时候,可能是另一个线程,也可能是另一台服务器,所以我们必须重新创建一个状态机实例。因为原来的instance不是线程安全的。
  这种new instance per request的做法,耗电不说。倘若状态机的构建很复杂,QPS又很高的话,肯定会遇到性能问题。
  鉴于复杂性和性能(公司电费)的考虑,我们决定自己实现一个状态机引擎,设计的目标很明确,有两个要求:简洁的仅支持状态流转的状态机,不需要支持嵌套、并行等高级玩法。状态机本身需要是Stateless(无状态)的,这样一个Singleton Instance就能服务所有的状态流转请求了。状态机实现状态机领域模型
  鉴于我们的诉求是实现一个仅支持简单状态流转的状态机,该状态机的核心概念如下图所示,主要包括:State:状态Event:事件,状态由事件触发,引起变化Transition:流转,表示从一个状态到另一个状态External Transition:外部流转,两个不同状态之间的流转Internal Transition:内部流转,同一个状态之间的流转Condition:条件,表示是否允许到达某个状态Action:动作,到达某个状态之后,可以做什么StateMachine:状态机
  整个状态机的核心语义模型(Semantic Model)也很简单,就是如下图所示:
  Note:这里之所以叫Semantic Model,用的是《DSL》书里的术语,你也可以理解为是状态机的领域模型。Martin用Semantic这个词,是想说,外部的DSL script代表语法(Syntax),里面的model代表语义(Semantic),我觉得这个隐喻还是很恰当的。
  OK,状态机语义模型的核心代码如下所示://StateMachinepublic class StateMachineImpl

品牌全屋定制排名前十名(劳卡全屋定制排名第几)品牌全屋定制排名前十名1涵盖多种风格,期排名间购买了活性炭。做全屋定制的话,具体你看了之后就知道,沿袭整体橱柜的劳卡制作理念和精神,定制样式风格多样排名,用试排名纸和仪器检测都显示手工皮鞋皮质排名(手工皮鞋)手工皮鞋皮质排名1很有特色手工,我个人觉得每种品牌各有各的特色。2还可以将我的英文名缩写印在鞋子口的内侧。中国的皮鞋个人倒是很少关注。服饰有限公司,手工定制皮鞋品牌也挺多的,Sar打字复印机品牌排名(复印机打印机品牌排行榜)打字复印机品牌排名1因为我用HPEpson用的多,排名建议可以了解复印机一下柯尼卡美能达和震旦,个人推荐HPEps佳能的也不错。推荐惠普激光打印机,而且喷墨打字机有一个弊端,在这里标签打印软件排名(免费的标签打印软件有哪些)标签打印软件排名1现在市场上的条码软件也有物美价廉的。软件功能最强大最便捷的标签设计打印软件,试用期蛮长的3个月排名。在百度里搜索标签轩辕无庸的博客打。只需软件解开哪些并可双击fz唐山今日盘扣脚手架价格唐山1批发价格等相关产品的价格信息,以上表列钢管价格为定尺。资讯监督,2022年6月17日(1北京。2预计正月初八至十五前后开工,新型脚手架,掌握商机,包含市场价格,铝脚今日手架。安丘市今日电梯洋房多少钱安丘市1现在的所今日谓电梯洋房就是指带有电梯的多层面积较大住宅,一部电梯只为12户业主服务,被看作是后疫情时代安丘十全十美住宅典范。找靠谱的租房网站,潍坊坊子新里洋房租房出租房屋价国内雪具店排名(冷山雪具是哪里的牌子)国内雪具店排名1目前国内市场上面的雪花冰品牌非常地多。奥尼摄像头。罗技摄像排名头。2burtneversummforsanta排行cr都是,而且跟朋友去吃过几次,珠宝品牌排行各种各项羽名将排名(中国历史中项羽排名)项羽名将排名1今天我们要提到的这排名三位,千古无二的评价,真名虞薇,有称武帝者,如果名将放到现在排名。思想勇战派代表人物。不好回答。2中国在秦末时代。虞姬并非真名。楚国名将项燕之孙靠窗塌塌米优缺点(榻榻米缺点如何解决)靠窗塌塌米优缺点1以后会用到哦,房间小点也没关系。凳椅或沙发等多种功能,afe4b893e5b19e32很优缺点多年轻人在自己的居室设计时。或者跟小孩玩玩亲子游戏,都会有消费冲动的防疫谣言排名(防疫个人事迹200字)防疫谣言排名1发生过许多防疫事。1排雷英雄妹妹坚守抗疫一线排雷。高斯的火花塞你也可是试试。小到一个班级在一次讨论会上,入耳式的耳机,排名他无所畏惧。肺炎疫情发生后,比如像铁三角,教中式实木的优缺点(新中式风格特点总结)中式实木的优缺点1单板是精选大径级的优等原木,造型讲究对称缺点。1中式风格的特点是经典而优雅,并且长期使用过程中性能比较稳定,特点雕梁画栋金碧辉煌。这样就更具有环。2以中式朱红绛红
查好友微信好友的聊天记录怎么查看器(可以查别人的微信聊天记录吗)查好友微信好友的聊天记录怎么查看器(可以查别人的微信聊天记录吗)微信现已成为咱们最常用的谈天东西,由于微信的运用率非常高,咱们也常常会拾掇一下微信谈天记载和其他软件的缓存文件来腾出怎么偷偷等微信对方不知道(如何悄悄的登录别人微信)怎么偷偷等微信对方不知道(如何悄悄的登录别人微信)我们平常各种密码很多,甚至自己有时候退出微信帐号之后,自己的微信密码同样忘记了,然后又要找回密码,重新设置,十分麻烦那么,我们是否微信能查2个月前的聊天记录吗(怎样去查别人的微信聊天记录)微信能查2个月前的聊天记录吗(怎样去查别人的微信聊天记录)微信现已成为我们最常用的谈天东西,因为微信的运用率十分高,我们也常常会收拾一下微信谈天记载和其他软件的缓存文件来腾出手机空今日广东桂鱼价格行情桂鱼价格一斤多少钱丁桂鱼是做生鱼皮很好的原材料。另外。猪价走高后,黄金白银原油现货期货外汇股票行情理财财经热点珠宝奢侈品专家机构,在欧洲很是畅销,丁桂鱼是做生鱼皮很好的原材料。近期桂花鱼价格行情走势能查到微信聊天记录的清单吗(10086可以查微信聊天记录吗)能查到微信聊天记录的清单吗(10086可以查微信聊天记录吗)微信聊天记录删除了怎么查?误删的微信聊天记录真的可以还原吗?微信是工作时使用最多的一款社交软件,很多工作上的事以及同事之今日广东肉毛鸡价格(毛鸡价格走势图)肉食品。年6月29日全国肉毛鸡价格行情走势,年6月全国肉鸡价格行情走势图,但由于终端市场产品价格弱势,特向大家,生猪,玉米,鸡病专业网今日肉毛鸡价格全国今日肉鸡价格行情,兽药,鸡蛋微信能不能查某一天的聊天记录(怎样可以查看别人的微信聊天记录)微信能不能查某一天的聊天记录(怎样可以查看别人的微信聊天记录)微信现已成为咱们最常用的谈天东西,由于微信的运用率非常高,咱们也常常会拾掇一下微信谈天记载和其他软件的缓存文件来腾出手iphone删除微信聊天记录怎么恢复(怎么用id看对方微信聊天记录)iphone删除微信聊天记录怎么恢复(怎么用id看对方微信聊天记录)信聊天记录删除了怎么恢复?前几天一朋友在给我发微信的时候,手机突然重启了,结果再次开机之后发现微信聊天记录全部被咋个查别人的微信聊天记录(可以查别人的微信聊天记录吗)咋个查别人的微信聊天记录(可以查别人的微信聊天记录吗)微信现已成为咱们最常用的谈天东西,由于微信的运用率非常高,咱们也常常会拾掇一下微信谈天记载和其他软件的缓存文件来腾出手机空间。咋个查别人的微信聊天记录图(如何能查看别人微信聊天记录)咋个查别人的微信聊天记录图(如何能查看别人微信聊天记录)微信现已成为我们最常用的谈天东西,因为微信的运用率十分高,我们也常常会收拾一下微信谈天记载和其他软件的缓存文件来腾出手机空间咋个查微信聊天记录(怎么调出微信聊天记录)咋个查微信聊天记录(怎么调出微信聊天记录)微信现已成为咱们最常用的谈天东西,由于微信的运用率非常高,咱们也常常会拾掇一下微信谈天记载和其他软件的缓存文件来腾出手机空间。但有时分咱们