MDA之路

MDA,UML,XML,Eclipse及Java相关的Blog
posts - 53, comments - 494, trackbacks - 0, articles - 2
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

漫谈OCL概念、特征和实践

Posted on 2005-04-04 22:42 wxb_nudt 阅读(3372) 评论(7)  编辑  收藏 所属分类: 技术杂谈

漫谈OCL概念、特征和实践

闲聊:

Jos WarmerObject Constraint Language, The: Getting Your Models Ready for MDA, Second Edition》终于看完了。这是一本不可多得的好书,一本好书可以让人节约很多的时间,其实我一直在寻找MDA相关规范的书,这本OCL是我认为最好的一本。关于MOF规范一直没有由浅入深的教程。XMI倒是有一本《精通XMI》,不过也不甚精彩。UML当然汗牛充栋,这倒不必多说了。

OCL概念

我的BLOG上面两篇都是介绍OCL的,导致人气低迷,本来关注MDA技术的人就不多,关注OCL的就更少了。不过无论如何,OCLMDA技术中不可缺少的部分。OCL虽然号称“对象约束语言”,不过实际上可以用来约束MOF四层模型中任意一层的模型以及实例。它真正的意义是建模相关领域约束语言。

除了约束模型以外,OCL的一个重要用途是可以用来描述模型转换规则。虽然这并不是OCL的主要用途(我没有仔细查阅OCL规范,不知道是否在规范中正式提出过这个用途),但是很多研究者进行了研究和探索。其中Jos Warmer专门在一节中讨论了这个问题。下面是摘自他文章中的一个用OCL描述模型转换的例子:

1.  自然语言描述的转换规则

·         For each class named className in the PIM, there is a class named className in the PSM.

·         For each public attribute named attributeName : Type of class className in the PIM the following attributes and operations are part of the class className in the target model.

- A private attribute with the same name: attributeName : Type

- A public operation named with the attribute name, preceded with 'get' and the attribute type as return type: getAttributeName() : Type

- A public operation named with the attribute name, preceded with 'set' and with the attribute as parameter and no return value: setAttributeName(att : Type)

从上面可以知道,这是一个将PIM中的class转换为PSMclass的规则,以及为private属性添加gettersetter方法。

2.  OCL写的转换规则,其中用到了作者自己发明的伪符号

Transformation ClassToClass (UML, UML) {

  source c1: UML::Class;

  target c2: UML::Class;

  source condition -- none

  target condition -- none

  mapping

         try PublicToPrivateAttribute on

                        c1.features <~> c2.features;

         -- everything else remains the same

}

Transformation PublicToPrivateAttribute (UML, UML) {

  source sourceAttribute : UML::Attribute;

  target targetAttribute : UML::Attribute;

         getter          : UML::Operation;

         setter          : UML::Operation;

  source condition

         sourceAttribute.visibility = VisibilityKind::public;

  target condition

         targetAttribute.visibility = VisibilityKind::private

         and -- define the set operation

         setter.name = 'set'.concat(targetAttribute.name)

         and

         setter.parameters->exists( p |

                       p.name = 'new'.concat(targetAttribute.name)

                       and

                       p.type = targetAttribute.type )

         and

         setter.type = OclVoid

         and -- define the get operation

         getter.name = 'get'.concat(targetAttribute.name)

         and

         getter.parameters->isEmpty()

         and

         getter.returntype = targetAttribute.type;

  mapping

         try StringToString on

                     sourceAttribute.name <~> targetAttribute.name;

         try ClassifierToClassifier on

                      sourceAttribute.type <~> targetAttribute.type;

}

-- somewhere the rules StringToString and ClassifierToClassifier

-- need to be defined

看来作者很有兴趣扩展OCL,将它变为Model Transformation Language

另外,Kent大学的研究者D.H.Akehurst在《Relations in OCL》(http://www.cs.kent.ac.uk/pubs/2004/2007/index.html)一文中专门做出了探索。这篇文章的大意是:扩展目前的OCL,将Relation(关系)作为first class(第一性的)元素加入OCL语言,然后利用Relation和目前的OCL相结合来描述模型转换规则(这篇文章我也许会在以后专门讨论)。中文的例子比较长,相关知识较多,就不列举了。

OCL特征

关于OCL的特征书中做出了总结,这里我没有回头仔细找,而是就脑海中最深的一些映像说几点。

OCL是一个查询性的语言,也就是说任何OCL的动作都不会对模型本身造成任何的影响或者改变。例如select操作,选出原来Set的一个子集,collect操作,将原来集合中的一些元素的值组成另一个集合。这些操作都不会对模型本身造成影响,最多就是构建了另外的对象或者集合。

OCL是一个强类型的语言,任何一个元素,都是有类型的,并且任何操作的返回值一定有一个确定的类型。如果不能确定类型,那么此元素属于OclVoid类型的值UndefinedOCL的类型有三种:基本类型(IntegerBoolean等)、Collection类型(五种,虚类型Collection,以及它的子类型SetOrderedSetBagSequence)和自定义类型(UML类,AssociationEnumeration等等)。

OCL里面很强调时间点,任何操作都定义为瞬时完成的,即操作中模型的状态不会改变。基于实现考虑,这么规定有一定的道理,不然在多线程系统中,OCL约束很有可能失效。另外preconditionpostcondition也明确规定是在方法执行的前后时间点才有约束,时间点不对约束无效。

OCL是一个宣言式(Declarative)的语言,描述了what to do,没有描述how to do。例如self.attribute->select(i| i.name = ‘wxb_nudt’)描述了将某个类的所有attribute组成一个集合,然后将属性名为wxb_nudt的属性提取出来组成一个子集(显然这样的属性不会多于一个,但这并不是我们关心的问题)。这个表达式描述以上的目的,但是没有给出执行过程。

OCL是基于集合论和谓词逻辑的,这点从它的表达式中可以很轻易的看出来。但是并不是集合论中所有的集合操作在OCL中都具有相应的符号表达。例如映射(project)就没有。而且OCL没有证明集合论中的所有集合操作都可以用OCL中现有的操作组合出来。但是我们相信这一点(盲目的,我没有时间去证明这个,呵呵)。另外关于OCL操作的中止性没有得到证明,也就是说“不能确定每个OCL操作都可以在有限时间内完成”,并且OCL并不能保证任意的OCL表达式是可中止的(我感觉自己简直就在说废话)。其实OCL已经说明了,无论如何实现,OCL假定所有表达式的计算都在瞬间完成。

虽然这部分内容在前面的blog中提到过,不过那个时候仅仅是照本宣科,和现在心有所感是不一样的。

OCL实践

目前OCL没有标准的实现,Jos Warmer在他的个人网站上列出了目前可用的OCL实现列表http://www.klasse.nl/ocl/ocl-services.html

其中我选择了Kent大学的OCL实现。还是kent大学的D.H.Akehurst,他们的research team开发了一个KMFKent Model Framework),其中有一个OCL的实现。可以用来体验一下用OCL来编程(编程?不是建模么?)。下载地址http://www.cs.kent.ac.uk/projects/ocl/

需要给他们写email才能得到下载地址。

然后Zurich大学的一位研究人员写了这个版本的OCL的简单实践http://www.zurich.ibm.com/~wah/doc/emf-ocl/,源代码如下:

import java.util.List;

 

import org.eclipse.emf.ecore.EAttribute;

import org.eclipse.emf.ecore.EClass;

import org.eclipse.emf.ecore.EcoreFactory;

import org.eclipse.emf.ecore.EcorePackage;

 

import uk.ac.kent.cs.kmf.util.ILog;

import uk.ac.kent.cs.kmf.util.OutputStreamLog;

import uk.ac.kent.cs.ocl20.OclProcessor;

import uk.ac.kent.cs.ocl20.bridge4emf.EmfOclProcessorImpl;

 

public class OCLDemo {

 

       public static boolean checkOCLConstraint(OclProcessor processor, String expr, Object model) {

              List l = processor.evaluate(expr, model);

              return Boolean.valueOf(l.get(0).toString()).booleanValue();

       }

      

       public static void main(String[] args) {

              ILog log = new OutputStreamLog(System.err);

              OclProcessor processor = new EmfOclProcessorImpl(log);

              System.out.println(processor.evaluate("1+1"));

 

              processor.addModel(EcorePackage.eINSTANCE);

              EClass eClass = EcoreFactory.eINSTANCE.createEClass();

              eClass.setName("Library");

              EAttribute attr = EcoreFactory.eINSTANCE.createEAttribute();

              attr.setName("books");

              attr.setEType(EcorePackage.eINSTANCE.getEInt());

              eClass.getEStructuralFeatures().add(attr);

             

              System.out.println(processor.evaluate("context ecore::EClass " +

                            "inv:self.eAttributes->select(x|x.name='books')", eClass));

             

              System.out.println(processor.evaluate("context ecore::EClass " +

                            "inv:self.eAttributes->exists(x|x.name='books' and x.eType.name = 'EInt')", eClass));

             

              boolean pre = checkOCLConstraint(processor, "context ecore::EClass inv: not self.oclIsUndefined()",eClass);

              // do something with eClass

              boolean post = checkOCLConstraint(processor, "context ecore::EClass inv: self.eAttributes->forAll(c| not c.changeable)",eClass);

              if (!(!pre | post))

                     System.out.println("OK.");

              else

                     System.out.println("Ooops.");

             

       }

}

我在Eclipse3.0.1EMF2.0以及上面下载的OCLjava包环境下运行了这个例子,结果如下:

[2]

[[org.eclipse.emf.ecore.impl.EAttributeImpl@62937c (name: books) (ordered: true, unique: true, lowerBound: 0, upperBound: 1) (changeable: true, volatile: false, transient: false, defaultValueLiteral: null, unsettable: false, derived: false) (iD: false)]]

[true]

OK.

例子很简单,详细的解释在上面链接的文章中解释了。但是这个例子仅仅构造了一个简单的ECore模型,而且是在程序中构造的,不是使用EclipseUML或者EMF画出来的,另外如何将OCL和模型连接起来也没有提到。如果有时间,我会看看KMF的文档,应该有答案。

后记

目前对OCL有了基本的把握,现在缺少的就是一个具体系统的构建实践。希望在EclipseEMFEclipseUMLKMF的环境下来完成这个例子。


评论

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2005-12-26 15:47 by 李海燕
我刚才看了你上面说的转换方式,以及与此相关的相关内容,我自己做了一个blog,我们公司也有自己的网站但是我试着用了以上你所说的方法,发现好象没有达到预期的效果,例如我用了你说的怎样把html转换为xml语言的代码,但是发现它是自动转换为html的,并且在预浏览时看不到预期如你所说的效果,到底是什么原因我最后看到的还是html语言,他们到底如何实现有效的转换呢?请高手指教,我的msn是xglhyaizhongguo@msn.com,希望您可以和我探讨这个问题。谢谢!。。。。。

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2005-12-26 18:14 by wxb_nudt
你的回帖贴错地方了吧?这篇随笔没有提到从HTML到XML的转换啊。那应该是XSLT相关的内容吧。
我不用MSN的,qq和邮箱都有,你可以用邮件和我联系。

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2006-09-05 17:41 by Martin Li
你好,我是最近才接触到OCL的,想对它有一些了解,别人给我推荐的书就是Object Constraint Language, The: Getting Your Models Ready for MDA, Second Edition。你那里有电子版吗,如果有能否发给我一份谢谢,我的邮箱fflgy@yahoo.com.cn

# 文章巨好,顶!!  回复  更多评论   

2007-09-09 09:43 by MDA中人
斑竹,你好,我一直在找OCL的相关规范,你看的Jos Warmer的Object Constraint Language, The: Getting Your Models Ready for MDA, Second Edition。你那里有电子版吗,如果有能否发给我一份谢谢,我的邮箱zh.hdong@163.com。

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2007-12-05 13:22 by 千寻
你好,我最近才接解MDA相关的,也想看看你推荐的这本OCL书籍,如果有电子版的话,能否给我发一份,谢谢了哈,偶的邮箱是hongyuanjx2002@163.com

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2009-01-14 17:45 by 初学MDA
你好,我是刚刚接触MDA,关于OCL的书籍(中文的更好!),能给我也发一份电子版的吗?谢谢!我的邮箱:hellochenyj@163.com

# re: 漫谈OCL概念、特征和实践  回复  更多评论   

2013-01-12 10:28 by lincoln
文章写得很好!赞一个!

我想问一下《Object Constraint Language, The: Getting Your Models Ready for MDA, Second Edition》这本书有没有随书光盘或者书中示例文件的下载地址?

我想看着实际例子来学,效果会非常好。

只有注册用户登录后才能发表评论。


网站导航: