初学者关于OCL及派生属性的使用问题咨询
OCL未赋值场景下的派生属性实现方案
现有两种思路的问题
- 第一种derive自引用思路:
直接在derive表达式中引用genericAttribute自身会触发无限递归求值。OCL派生属性默认动态计算,每次访问属性都会执行derive表达式,表达式内再次访问属性会重复触发计算流程,最终导致栈溢出。 - 第二种inv约束思路:
inv是不变量校验规则,仅负责验证模型状态是否符合要求,不具备自动赋值能力。如果属性未赋值,只会触发不变量校验失败报错,无法自动注入派生值作为默认值。
符合OCL 2.5规范的正确实现
场景1:属性支持显式赋值,无赋值时使用派生默认值
这是需求对应的标准实现,使用OCL标准元操作oclGetSlotValue直接读取属性的底层存储槽,不会触发派生计算,避免递归:
context GenericClass::genericAttribute : PrimitiveType derive: if self.oclGetSlotValue(GenericClass::genericAttribute).oclIsUndefined() then <匹配类型的派生表达式> else self.oclGetSlotValue(GenericClass::genericAttribute) endif
注意:需要将属性的元属性设置为
isDerived = true、isReadOnly = false,才允许外部显式赋值覆盖默认派生值。
场景2:属性为只读派生属性,仅依赖其他属性计算
如果不需要支持外部赋值,只需要在依赖属性未定义时返回默认值,不要引用属性自身,直接判断依赖属性状态即可:
context GenericClass::genericAttribute : PrimitiveType derive: if <依赖属性>.oclIsUndefined() then <默认值表达式> else <正常派生逻辑表达式> endif
旧版本引擎兼容方案
如果所用的OCL执行引擎不支持oclGetSlotValue,可以新增一个私有存储属性genericAttribute_stored专门保存显式赋值,派生属性基于该私有属性判断:
context GenericClass::genericAttribute : PrimitiveType derive: if genericAttribute_stored.oclIsUndefined() then <匹配类型的派生表达式> else genericAttribute_stored endif
内容的提问来源于stack exchange,提问作者BMH_H20
相关产品推荐
相关产品推荐

