微软在VS2005SDK中开始提供了DSL,也出了一本专门写Visual Studio DSL的书籍,这本书较为详细的介绍了一下DSL的内容,在目前DSL书籍较少的环境下,有这么一本书可以参考还是不错的。
我几年前就看过了这本书了,由于最近开始考虑给OpenExpressApp增加模型驱动开发的建模支持OpenMetaEdit,所以又重新看了一下,现在把书中一些非Visual Studio特有的知识摘录如下,对DSL感兴趣的可以学习下。
- 特定领域开发是通过设计一种用于特定目的的语言,使软件开发中遇到的大多数问题更容易解决。
- 如果仅适用通用编程语言,则每次只能解决一个问题,但如果应用特定领域开发方法设计并实现一些特殊语言,每个特殊语言可以高效地解决一类相似的问题
- 特定领域语言可以使文本语言,也可以是图形语言。
- 图形语言不只是图表,否则使用Visio之类的画图软件就行了,它实际上是要创建模型,这个模型要能够从概念上描绘你正在创建的系统,并对其内容进行图表化的表示。一个模型可以同时由多个图表来表示,每个图表表示模型的某个方面
- 文本语言用户输入,可以快速的打字。
- 文本语言的优势在于可以进行比较和合并,而图形表达式可以更容易的看出内容之间的关联。
- 相对来说,文本语言比图形复杂
- 特定领域开发时一种用于解决重复发生的问题的方法。对于问题的每次发生,就用这个特殊语言建立模型或表达式,然后把模型插入到解决方案中的固定部分。解决方案中的固定部分采用传统的设计、编码和测试技术实现,根据药解决问题的规模和种类,固定部分可以是框架、平台、解释器或API。固定部分确立了构成问题域的结构模式,同时也提供了可扩展性,从而可用到多个解决方案中。
- 软件开发过程定制
- 找出所有问题中的固定部分,并把这些固定部分放在通用架构或平台中
- 找出所有问题的变化部分,并设计一种DSL,DSL的表达式或模型可以给出问题的一个解决方案
- DSL应用的优点
- 特定领域语言的定义:
特定领域语言是针对小的问题领域而定制的语言,它使用该领域特有的术语对问题进行描述和验证 - 特定领域开发与许多其他作者和机构的创造密切相关,一下列出了其中一部分:
- 模型驱动开发 MDA
- 面向语言编程 LOP
- 语言工作平台 Language Workbenches
- 特定领域建模 DSM
- 产生式编程 Generative Rrogramming
- 意图软件 Intentional Software
- 软件工厂 SOftware Factories
- 表示结构的规范:结构容器、隔间、连接线、重数、端口
- 表示行为的规范:生命线和箭头、箭头、泳道、小人
- 图形DSL有几个重要内容必须要定义:符号、域模型(域类和关系、约束)、生成、序列化和工具集成
- DSL工具采用自举的方式由DSL定义生成,系统的核心是那些自动生成的代码,并通过手写代码对其进行功能扩展
- 对于大多数情况,DSL主要是对通用框架参数化的途径
- 为了降低风险,我们并不是马上就从头开始开发框架及其DSL,而是从现有的可以在某些应用中使用的代码开始,逐步的对其进行参数化,逐步的发现那些在不同应用中变化的部分,然后使这些部分依赖于DSL
- 自上而下的方法倾向于快速建立一个完整且自包含的模型,具有更长远的考虑,有助于保证结构的一致性。但是从另一方面看,这种方法容易导致在概念层设计出很复杂的模型,并且该模型难于实现。因此在实际应用中,将自上而下和自下而上两种方法交替使用会更有效。采用渐进的方式可以避免早期投入过大风险,但是需要定期进行一致性检查
- 采用DSL的一个作用就是,使工作更贴近于客户的理解,而不是实现本身
- 表示层和底层模型相互分离的设计,使得DSL编写者可以在不改动模型的情况下,合理改变域模型的表示方式。在DSL保存时产生两个文件,一个文件包括域类和关系的实例,以及它们的属性信息,另一个文件则包含用于图形化显示的布局信息
- 当要生成大量的代码时,用运行时参数化的通用代码替代部分代码会更有好处
- 由DSL驱动的应用程序:生成式应用,解释式应用。在某些情况下,系统可能需要从生成式框架演变到解释方式框架,以增强更多的运行时灵活性
- 一个DSL实现的结构主要分为三层:编译好的框架,由DSL定义生成的代码,以及自动以代码
Microsoft.VisualStudio.Modeling:域模型框架时整个系统的核心,负责管理模型的元素和连接,也就是域类和域关系的实例。
Modeling.Disgrams:设计界面框架建立在域模型框架之上,它负责处理图形符号的显示,包括处理图表、图形、连接器和装饰等元素在设计界面上的显示
Modeling.Validation:验证框架负责执行关于模型元素和连接的验证方法,如果验证失败,它还要负责创建错误对象。它与Shell框架交互,把错误信息显示到Visual Studio的错误窗口
Modeling.TextTemplation:模板引擎负责执行文本模板来生成代码或其他的工件。模板引擎室一个独立的组件,用于执行来自非DSL的模板输入
Modeling.Shell:建模用的Shell负责管理将涉及器集成到Visual Studio中,例如处理工具窗口和菜单名利,以及文件的打开和关闭等 - 每一个DSL的核心都是一个域模型,它定义了这一预言所代表的各种概念,这些概念的属性,以及它们之间的关系
- 形状:集合形状、隔间形状、图像形状、端口、泳道
- 选择硬约束还是软约束
- 硬约束指的是工具从不让用户违反的那些约束,例如在一个形状元素的“宽度”字段中,只允许有效地数字
- 软约束是指用户在有时可以违反,而有时有不能违反的那些约束,例如模型中所有的元素都要有唯一的名字
- 大多数约束的计算量都不小,用户并不是在任何时候都一直需要正确的模型
- 将重数的最大值作为硬约束,而把最小值作为软约束
- 当使用DSL工具在概念层建模时,经验证明,一个有用的做法是实用字符串作为基本属性类型,然后用一组软约束检验属性的值符合更为严格的类型集
- 单独使用硬约束不会带来最佳的用户体验,因为硬约束只是不让用户及逆行那个任何违反规则的操作,而不是引导用户的使用体验
- DSL的一个最重要的应用是用来生产简单的文本形式的工件,例如源代码、数据库脚本,或者是另一个DSL的持久化表示
- 目前DSL工具并不提供对同步的直接支持,这是因为除了少数DSL,同步的复杂程度通常超过了其带来的收益。
- 设计DSL
- 识别可变性与发现DSL:DSL是用你的框架具体的实现你的体系架构模式中可变的部分
- 开发领域模型捕获可变性
- 定义标记:在适当的地方使用常见标记法或与标记法相关的约定
- 开发验证的约束:识别树形之间的依赖性,认出快照中的强制或禁止的循环
- 开发并演进框架:理解你的DSL针对的代码体系结构,并在框架中编写它
- 测试DSL:包括验证的约束与规则、生成器与命令、以及生成的代码
- 演化和移植DSL:确保旧的模型在新版本的DSL中能够使用
- 识别好的DSL:范围、最小性、常见标记法,适度的冗余,合理的使用句法空间,使用用户术语
- 特殊树是自顶下下考虑及捕获变化的一种技术。
- 这棵树概念上包括需求文档的每一个特征,其中有些特征可能最终也是不可选的。
- 特征树是针对需求而不是设计的,每个特征描述了系统中的一些客户可见的东西。许多变动时关于设计抉择的变化,而不是需求变更,例如在某处使用list代替array,这些变化不包含在特征树中
- 特征树不只包括最终用户的可见特征,当你设计某些类似通用向导构建器的东西是,你的客户是调用你的子系统的开发者,特征是那些在你的API中对他们是可见的行为
本文转自 jingen_zhou 51CTO博客,原文链接:http://blog.51cto.com/zhoujg/522558,如需转载请自行联系原作者