分享

eclipse EMF介绍系列(EMF与MDA)

 碧海山城 2010-05-26

接触Eclipse一段时间的朋友应该都听说过EMF这个名字,EMF是Eclipse Modeling Framework的缩写,它是Eclipse的一个重要的子项目,如果翻译成中文就是“Eclipse建模框架”。其实只从这个名字还真是难以确定它的作用是什么,我认为要完全掌握EMF应该对模型驱动开发(MDA,Model Driven )有一定的了解,而EMF可以看作是Eclipse上的MDA一个实现(代码生成是MDA 的重要组成部分之一),它能够生成在Eclipse上执行的代码。可惜我对MDA没有系统研究过,对EMF的应用大多是为了减少模型修改带来的影响,所以也希望EMF能带我进入MDA的世界。

MDA讲究的是把模型和应用系统实现分开,模型是最重要的部分,可以说有了清楚的模型,就完成了一半的工作。模型是由元模型(Meta Model)定义的,例如UML里“类”和“属性”这些概念是在UML的元模型里定义的,而元模型又是由“元元模型”来定义,后者多是自描述的,也就是能够自己定义自己,所以很少见到“元元元模型”的概念。在MOF规范里,元元模型处于M3层,元模型处于M2层,往下的M1层是模型,而M0层是实例。EMF定义了一套Ecore元模型,该模型是EMOF(MOF的一个子集, MOF是Meta-Object Facility的缩写)的一个实现,这是一个自描述的模型,可以认为它处于MOF中的M2层,即与UML元模型相同的位置。用Ecore元模型可以定义 ecore模型,也就是.ecore文件,这个模型处于M1层,而ecore模型的实例处于M0层。关于MOF的更多概念请参考MOF规范和相关文档, MDA的各种概念是相当多的,研究它的人也很多,我认为EMF算是比较务实的一派。如果以后有机会深入研究Ecore元模型,我也会把心得写在这里供大家参考。

EMF自发布以来一直受到Eclipse社区的热情拥护,目前很多Eclipse的子项目都是基于它开发的,可见EMF确实能给开发者带来好处。随着EMF的成长,出现了越来越多的文档,在/emf上就可以找到不少,最全面和权威的当属这本Eclipse Modeling Framework A Developers Guide,完整的讲解了EMF,虽然针对的版本较早,但绝大部分内容还是适用的;作为入门读物,网站上Documents里列出的一些教程也是不错的选择;EMF的新闻组更是一个很好的交流场所,Ed Merks(EMF设计师之一)和其它几位开发人员可以说是有问必答,感谢他们的认真态度。

通过在一些项目里使用EMF,我也逐渐感觉了到它起到的作用,特别是当模型里各种元素和关系比较多时,EMF的代码生成功能会节省不少工作量,对于我们开发人员来讲,这不就是最大的好处吗。其实用EMF构造一个应用的步骤很简单:1、构造模型,2、生成代码,前者可以通过UML类图、Java接口、 XML Schema等多种方式定义,后者可以选择只生成模型部分的代码,也可以同时生成编辑器部分的代码,对这个编辑器做一些定制就可以得到符合需求的应用程序。

类图可以帮助我们直观的了解应用系统里各对象的关系,但在开发过程中,类图里的定义很可能被修改,如果这一修改没有及时反映回类图,类图就会逐渐变得不准确而失去作用。但是保持代码和类图的一致是一件很烦琐的工作,有时由于项目管理的需要,类图又必须保证能够反映系统的真实结构。比较好的解决方法是让代码由类图直接生成,模型需要修改时也在类图上做改动,并且重新生成代码,这正是EMF的专长。

说了这么多,你可能还是没弄明白EMF到底能为我们带来哪些好处,是怎样为我们节省工作量的,从下个帖子开始我们将一步步了解怎样使用EMF构造应用程序。因为是边用边写,所以这个系列的帖子都不会太长,相信后面部分会以心得和技巧等内容为主。

 
 
EMF介绍系列(从模型生成应用程序)

还是从一个例子里看看EMF的使用方法和作用吧。假设我们的应用是一个网上商店,在系统里有这些对象:商店Shop、类别Category、商品Product,其中类别可以包含子类别。现在我们用EMF从头到尾生成一个可以管理类别和商品的应用程序。如果你的Eclipse里还没有安装 EMF,在/emf下载适合你Eclipse版本的EMF SDK,建议你下载全部包含的那种。安装后,在新建对话框里会增加EMF的类别,如图1所示:


图1 新建向导里的EMF类别

其中“EMF Model”是从已有的模型文件创建genmodel模型,这个模型是专门用来生成代码的;如果你手里已经有一个模型(比如一个.mdl文件或是一个.xsd文件等等),可以选择新建“EMF Project”,这样在向导的后面部分里会要求提供已有的模型文件;因为我们打算自己从头开始建立这样的模型,所以选择“Empty EMF Project”,和建立普通插件一样,要提供一个插件名称,我们为这个商店项目起名为com.my.shop,然后按Finish即完成向导。目前这个新建立的项目里还没有包含任何代码,只是在META-INF/MANIFEST.MF文件里定义了对EMF相关插件的依赖。

下面开始定义ecore模型,我比较喜欢图形化的方式,因为看起来很直观,所以我使用Omondo公司的EclipseUML插件来画类图,这个插件的免费版本在 它们网站下载,注意下载适合你的Eclipse的版本。当然rose也不错而且更加稳定,但它不是免费的,而且只能在Windows里使用。和Rose不同,EclipseUML对EMF有特别的支持,安装这个插件后,我就们可以在项目里新建一个“EMF Class Diagram”,这样会同时创建一个.ecd文件和一个.ecore文件,EclipseUML编辑的类图信息会保存在这两个文件里,前者主要是图形方面的内容,而后者是真正的模型信息,注意这两个文件中的任何一个都不要搞丢了,最好能经常备份一下。

在EclipseUML里编辑类图很简单,需要注意的是,两个对象之间如果有关联,要仔细考虑关联是否为“包含”关系(一般在UML中以黑色菱形表示),如果一个类没有包含在任何其它类里,则这个类的实例不会被保存到文件。例如图2中Category包含在Shop中,Product包含在 Category中。这样,所有的对象都直接或间接的被Shop对象包含。换句话说,如果以Shop作为“根”,所有的对象都可以被保存到文件里。

EMF对java基本类型和一些常用类做了包装,例如int->EInt,java.lang.Integer->EInteger以及java.util.List->EList等等,所以在定义类的属性时要使用这些EMF的类型,当然也有办法使用自定义类型(以后会用到)。我们例子里的模型相当简单,一共只有三种业务对象(为了更加直观,我们增加了一个NamedElement接口),现在网上商店类图的第一个版本如图2所示。


图2 网上商店类图(版本1.0)

接下来就要生成代码了。EMF使用JET利用模板生成代码(前面曾介绍过JET),所以要把ecore模型转换为可以被JET利用的genmodel模型,具体的操作是按 ctrl+n新建一个EMF Model,在这个向导的第一步指定名称shop.genmodel,第二步选择从ecore模型导入,第三步选择ecore模型文件(shop.ecore),这样就建立了缺省的genmodel模型,在这个模型的基础上还可以做一些定制工作,例如每个属性的描述信息等等。

有了genmodel模型,离得到可用的java代码就只有一步之遥了。打开shop.genmodel文件,在根节点上点开右键菜单(见图3),如果只想生成模型代码选择“Generate Model Code”,如果需要.edit的代码(EMF提供的一些ItemProvider和AdapterFactory,帮助实现编辑器)和可用的编辑器,选择“Generate All”最方便,这也是例子里选择的方式。EMF的代码生成器为模型、.edit、编辑器和测试代码各生成一个插件项目(com.my.shop/shop.edit/shop.editor/shop.tests),前三个是后者依赖前者的关系。这里插上一句,即使没有用EMF的项目,也建议把模型和界面使用不同的插件项目分开,这样做有很多好处,主要是灵活性大大提高了。


图3 从菜单里选择生成部分或全部代码

现在可以运行起来看看效果了,注意我们甚至连一句代码也没有写呢。EMF为我们生成了一个新建向导(New Wizard),利用这个向导可以生成新的Shop实例,注意在第三步要选择以Shop类为根类型。编辑器的运行界面如图4所示,它的外观虽然有待改进,但功能已经足够我们对网上商店里的类别和产品进行编辑了。在以后的帖子里,我们要对网上商店的ecore模型和编辑器的界面做一些修改。


图4 缺省的编辑器界面

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多