打算从今天开始,系统的学习一下DSL相关技术。
这个系列的所有文档都来自于MF的BLIKI中的Domain Specific Languages,其余文字都是对其的理解和整理。
关于什么是DSL,之前的文章有提到过。
简单的说
DSL与通用语言相区别,是为特定目的而生的语言,它并不是什么新东西,历史几乎和计算机的历史一样长。
DSL的应用广泛而常见,比如CSS,比如Wiki。DSL通过分析特定问题域提炼动态模型,从而标准化问题处理流程。
恩,先从MM图看起:
重点概念
DSL的类型
DSL可以分为内部DSL(Internal DSLs)和外部DSL(Internal DSLs),主要区别在于其与实现语言的关系。
内部DSL的语法是其实现语言的子集,典型的如Ruby;外部DSL通常是定制的特殊语法,如HQL。
Language Workbenches 也是DSL实现的方式之一,特定的平台有其特殊性。
API风格的区别
传统意义的程序语言,在实现具体逻辑的时候,往往是一种命令查询风格API ;而DSL通常是口语化接口。
程序比较,都用Java实现
命令查询风格
Event doorClosed = new Event("doorClosed", "D1CL");
Event drawOpened = new Event("drawOpened", "D2OP");
Event lightOn = new Event("lightOn", "L1ON");
Event doorOpened = new Event("doorOpened", "D1OP");
Event panelClosed = new Event("panelClosed", "PNCL");
Command unlockPanelCmd = new Command("unlockPanel", "PNUL");
Command lockPanelCmd = new Command("lockPanel", "PNLK");
Command lockDoorCmd = new Command("lockDoor", "D1LK");
Command unlockDoorCmd = new Command("unlockDoor", "D1UL");
State idle = new State("idle");
State activeState = new State("active");
State waitingForLightState = new State("waitingForLight");
State waitingForDrawState = new State("waitingForDraw");
State unlockedPanelState = new State("unlockedPanel");
StateMachine machine = new StateMachine(idle);
idle.addTransition(doorClosed, activeState);
idle.addAction(unlockDoorCmd);
idle.addAction(lockPanelCmd);
activeState.addTransition(drawOpened, waitingForLightState);
activeState.addTransition(lightOn, waitingForDrawState);
waitingForLightState.addTransition(lightOn, unlockedPanelState);
waitingForDrawState.addTransition(drawOpened, unlockedPanelState);
unlockedPanelState.addAction(unlockPanelCmd);
unlockedPanelState.addAction(lockDoorCmd);
unlockedPanelState.addTransition(panelClosed, idle);
machine.addResetEvents(doorOpened);
口语化风格
doorClosed. code("D1CL");
drawOpened. code("D2OP");
lightOn. code("L1ON");
panelClosed.code("PNCL");
doorOpened. code("D1OP");
unlockPanel.code("PNUL");
lockPanel. code("PNLK");
lockDoor. code("D1LK");
unlockDoor. code("D1UL");
idle
.actions(unlockDoor, lockPanel)
.transition(doorClosed).to(active)
;
active
.transition(drawOpened).to(waitingForLight)
.transition(lightOn). to(waitingForDraw)
;
waitingForLight
.transition(lightOn).to(unlockedPanel)
;
waitingForDraw
.transition(drawOpened).to(unlockedPanel)
;
unlockedPanel
.actions(unlockPanel, lockDoor)
.transition(panelClosed).to(idle)
;
DSLs实现模型
实现DSL,主要是针对特定问题域进行动态状态建模,模型可以是任意的:对象模型,结构化模型或者其他的任何实现模型;程序语言通常会很关注语法以及语义,DSLs中的建模主要就是为了建立问题域的描述语义。
DSLs实现方法
代码生成(Code-Generation)和解释运行(Interpretation)是DSL的两种实现方式,前者在编译时处理模型,后者在运行时应用模型。
从实现的角度来讲,前者更加快捷方便,而后者更加精致有效;短期看代码生成可以很快应用,长期看解释运行更能形成效益。
2字节(2byte.us)