MetaModelEngine:约束和验证
在前一篇MetaModelEnginebolg中介绍了界面表示,本篇继续介绍一下约束和验证相关内容。
什么是约束
验证在我们开发中经常遇到,例如在强类型语言中,当我们敲错一个关键字,或者语法写错,当编译时就会报出错误。约束也很常见,例如主流的程序设计规范都建议使用断言(seertion),这样在调试时它就会对调用方法的合法参数值施加显示约束(如不允许传入空字符串等)。编程语言这样,对于建模语言呢?
建模中的情况其实也是类似的,它也有必须遵守的语法,例如表示门的类,其宽度和高度必须是浮点类型;我们还可以使用表达式或者脚本来支持用户自定义的约束。用语言来表述的模型约束的例子有很多,例如可以是:
- 消防员的身高属性必须大于1.8米
- 房屋必须至少有一个门
- 类定义不直接或间接地通过基类属性引用它自己
约束一般被认为是不变式,也就是说在模型的整个生命期中它的值都是真,或者在设计时(如代码生成、保存)或运行时(如计入借方银行账户)作为一些操作的先决条件或后续条件。在模型中常见的一种约束就是重数:
MetaEdit+中的约束(Constraints)
- 连接约束:例如,一个对象在某个特定角色中最多只能出现的次数
- 对象次数:例如,一个对象类型在一个图形中最能有特定数量的实例
- 端口约束:例如,在一个绑定中,一个特定类型的所有端口必须有同样的特定属性
- 属性唯一:例如,图中一个特定类型的所有对象的特定属性必须有一个唯一值
-
连接约束(Connectivity constraints)
-
对象次数(Occurrence constraints)
-
端口约束(Port constraints)
-
属性唯一(Uniqueness constraints)
验证类别
验证类别指的是在验证环节,一般可以有以下几种,这些具体细则还需要在设计时仔细考虑:
- 装载模型
- 打开
- 保存
- 各种菜单操作
- 自定义类别
[RuleOn(typeof(Generalization), FireTime=TimeToFire.TopLevelCommit)]internal sealed class CyclicInheritanceAddRule: AddRule
选择硬约束还是软约束
对于可视化设计器而言,约束可以分为以下两类:
- 硬约束:在任何时期都不能违反的强制约束,如一个形状元素的宽度必须为有效地数字,这个宽度设置在输入数字时就要进行及时的验证
- 软约束:用户在有些时期可以违反,而在另一种情况下又不能违反的约束,例如,模型中所有的元素都要有唯一的名字在更改名称时不检查,而在保存时再验证;还有比如建立多个属性时,最后才检验属性名称是否重复的约束
采用硬约束可以保证用户不会犯错误,所以在任何情况下把约束表达成硬约束。但是实际建模场景中,硬约束会带来两个实际应用中的问题:
- 大多数约束的计算量都不小,所以实时的大量计算验证可能会带来性能问题
- 用户并不需要在任何时候都一直需要正确的模型。有时我知道模型是错误的,但我有其他急的事情要处理,我这时候就希望能保存错误的模型,只是不提交运行而已。
单独使用硬约束不会带来最佳的用户体验,因为硬约束只是不让用户进行任何违反规则的操作,而不是引导用户进行正确的操作。对重数的一种处理方式就是:将重数的最大值作为硬约束,而把最小值作为软约束
提示:当使用DSL工具在概念层建模时,经验证明,一个有用的做法是使用字符串作为基本属性类型,然后用一组软约束检验属性的值符合更为严格的类型集
本篇参考
欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]