打算从今天开始,系统的学习一下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的两种实现方式,前者在编译时处理模型,后者在运行时应用模型。
从实现的角度来讲,前者更加快捷方便,而后者更加精致有效;短期看代码生成可以很快应用,长期看解释运行更能形成效益。