EMF学习笔记1——模型实体类
2010-11-02 20:15
162 查看
EMF是基于两种元模型来构建的,分别是Ecore和Genmodel。
Ecore:主要用于定义模型结构的相关信息,并对外提供了一个根对象(犹如XML文件的根节点)用来代表要显示的模型,该对象的子节点为package(包),package的子节点为class(类),class的子节点为attribute(类的属性字段),这样整个树形结构就代表了所要表示的EMF模型结构。
Genmodel:主要包含有关代码生成的相关信息(如:文件生成路径及文件名),和一些控制参数用来控制代码怎样生成。
EMF采用模型驱动开发方法,在无需编码的情况下,我们可以基于模型使用EMF为我们生成以下几样东西。
1,与模型相对应的EMF实体类。
2,基于实体类的各种ItemProvider模型适配器类,通过该适配器类可以很好的将EMF模型绑定到Jface组件中去,稍后具体介绍。
3,editor-plugin项目,可理解为基于EMF应用的一个插件项目。
4,测试bundle。
这里3和4不做介绍,主要讲解1,2。然后自定义一个Jface组件,将EMF模型应用与该组件之上。
在开始之前,我们需要了解以下几个名词的含义,也是文中多处提到的几个词:
1实体类:就像Hibernate ORM为我们生成的实体类一样,EMF也会为我们生成这样的实体类,并且这些实体类含有更高级的特性(如:类属性状态发生变化时,实体类具有通知功能)
2适配器类:EMF的模型结构可能非常复杂(如可能含有多个实体类,并且类结构各不相同),这样当视图组件直接使用这些实体类的时候就变得非常困难(要判断出是哪一个实体类,针对该实体类怎样显示视图等等..),因此EMF针对这些实体类生成了一些适配器类,通过实现指定的接口,让适配器类来设计实体类的显示,而视图只需要选择合适的适配类便可。
3适配器工厂:上面讲到视图通过适配器类避免了与实体类的直接交互,然而视图又是如何得到合适的适配器类的呢?那便是通过适配器工厂类。
模型定义如下:
从模型定义来看Library便是Ecore所对外提供的用来表示模型的根对象。
首先来看EMF为我们生成的模型实体类(假设这些实体类分布在org.emf.demo这个bundle之中)
EMF会为我们生成3个package,分别是:
org.emf.demo.library:包含实体类的接口;用于创建实体类的工厂(libraryFactory);访问模型元数据的实用类(LibraryPackage)
org.emf.demo.library.impl:实体类接口的实现类;实体类工厂的实现类(LibraryFactryImpl);LibraryPackage的实现类(LibraryPackageImpl)
org.emf.demo.library.util:针对该模型的适配器工厂类(LibraryAdapterFactory)
注:libraryFactory和LibraryPackage都是单例模式的,可通过其成员变量eINSTANCE来得到对象的实例。
在EMF中,所有的实体类接口全部继承EObject,换个角度,同Java领域的Object对象一样,EObject是EMF中所有类的基类。在实体类的定义中,我们强调过,除了具有一般JavaBean的特性之外,EMF实体类具有更高级的特性,因此其代码实现也较普通的javaBean更加复杂。
在EMF所生成的实体类的set方法中,除了要对成员变量进行赋值外,还要对其适配器类进行变更通知操作。以Book实体类的setPages方法为例:
当Writer和Book两个实体类分别存储与不同的资源文件中时,EMF是采用延迟加载模式来加载对象的,因此这里的Writer对象可能只是Writer的一个代理类,而不是真正的对象引用,所以在getWriter()方法里,首先要判断其是不是代理类(eIsProxy()方法),如果是则调用eResoleProxy()方法来加载目标对象,然后判断目标对象与代理对象是否相同(引用同一个对象),如果不同则Book的Writer属性状态便发生了变化,要对其适配器类进行通知。
双向引用(two-way reference):
同单向引用相比,get方法没有变化,set方法的实现不同。以Book对象的setWriter()方法为例:
虽然我们只是在book端执行了setWriter方法,而没有在writer端执行添加book的方法,但是在writer端依然能够遍历到Book对象。
聚合引用:
所谓聚合引用,就是一个对象是另一个对象的容器;比如上面的Library和Book,Library便是Book的容器。
在EMF中,容器和它所包含的对象存储在同一资源文件中,因此在加载的时候不需要使用代理机制。
在聚合引用中,每个对象只能有一个容器,因此在将一个对象加入到某个容器之前,要将该对象从现在的容器中移除出去。为了实现该功能,EObjectImpl类中设计了一个成员变量eContainer用来表示实体类对象的容器,这样我们就可以通过book.eContainer()方法来得到Library对象。
注:EMF所生成的变量或方法都会含有@generated标注,当执行regenerate操作时EMF只会覆盖含有@generated标注的方法,而自己手工添加的方法不会被覆盖。
下一篇将会讲解EMF所生成的适配器类。
Ecore:主要用于定义模型结构的相关信息,并对外提供了一个根对象(犹如XML文件的根节点)用来代表要显示的模型,该对象的子节点为package(包),package的子节点为class(类),class的子节点为attribute(类的属性字段),这样整个树形结构就代表了所要表示的EMF模型结构。
Genmodel:主要包含有关代码生成的相关信息(如:文件生成路径及文件名),和一些控制参数用来控制代码怎样生成。
EMF采用模型驱动开发方法,在无需编码的情况下,我们可以基于模型使用EMF为我们生成以下几样东西。
1,与模型相对应的EMF实体类。
2,基于实体类的各种ItemProvider模型适配器类,通过该适配器类可以很好的将EMF模型绑定到Jface组件中去,稍后具体介绍。
3,editor-plugin项目,可理解为基于EMF应用的一个插件项目。
4,测试bundle。
这里3和4不做介绍,主要讲解1,2。然后自定义一个Jface组件,将EMF模型应用与该组件之上。
在开始之前,我们需要了解以下几个名词的含义,也是文中多处提到的几个词:
1实体类:就像Hibernate ORM为我们生成的实体类一样,EMF也会为我们生成这样的实体类,并且这些实体类含有更高级的特性(如:类属性状态发生变化时,实体类具有通知功能)
2适配器类:EMF的模型结构可能非常复杂(如可能含有多个实体类,并且类结构各不相同),这样当视图组件直接使用这些实体类的时候就变得非常困难(要判断出是哪一个实体类,针对该实体类怎样显示视图等等..),因此EMF针对这些实体类生成了一些适配器类,通过实现指定的接口,让适配器类来设计实体类的显示,而视图只需要选择合适的适配类便可。
3适配器工厂:上面讲到视图通过适配器类避免了与实体类的直接交互,然而视图又是如何得到合适的适配器类的呢?那便是通过适配器工厂类。
模型定义如下:
从模型定义来看Library便是Ecore所对外提供的用来表示模型的根对象。
首先来看EMF为我们生成的模型实体类(假设这些实体类分布在org.emf.demo这个bundle之中)
EMF会为我们生成3个package,分别是:
org.emf.demo.library:包含实体类的接口;用于创建实体类的工厂(libraryFactory);访问模型元数据的实用类(LibraryPackage)
org.emf.demo.library.impl:实体类接口的实现类;实体类工厂的实现类(LibraryFactryImpl);LibraryPackage的实现类(LibraryPackageImpl)
org.emf.demo.library.util:针对该模型的适配器工厂类(LibraryAdapterFactory)
注:libraryFactory和LibraryPackage都是单例模式的,可通过其成员变量eINSTANCE来得到对象的实例。
在EMF中,所有的实体类接口全部继承EObject,换个角度,同Java领域的Object对象一样,EObject是EMF中所有类的基类。在实体类的定义中,我们强调过,除了具有一般JavaBean的特性之外,EMF实体类具有更高级的特性,因此其代码实现也较普通的javaBean更加复杂。
在EMF所生成的实体类的set方法中,除了要对成员变量进行赋值外,还要对其适配器类进行变更通知操作。以Book实体类的setPages方法为例:
public Writer getWriter() { if (Writer != null && Writer.eIsProxy()) { InternalEObject oldWriter = (InternalEObject)Writer; Writer = (Writer)eResolveProxy(oldWriter); if (Writer != oldWriter) { if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.RESOLVE, WebpagePackage.BOOK__Writer, oldWriter, Writer)); } } return Writer; }
当Writer和Book两个实体类分别存储与不同的资源文件中时,EMF是采用延迟加载模式来加载对象的,因此这里的Writer对象可能只是Writer的一个代理类,而不是真正的对象引用,所以在getWriter()方法里,首先要判断其是不是代理类(eIsProxy()方法),如果是则调用eResoleProxy()方法来加载目标对象,然后判断目标对象与代理对象是否相同(引用同一个对象),如果不同则Book的Writer属性状态便发生了变化,要对其适配器类进行通知。
双向引用(two-way reference):
同单向引用相比,get方法没有变化,set方法的实现不同。以Book对象的setWriter()方法为例:
LibraryFactory factory=LibraryFactory.eINSTANCE;//得到创建实体类的工厂类 Book book=factory.createBook();//创建Book对象 Writer writer=factory.createWriter();//创建Writer对象 writer.setName("zhangsan"); book.setTitle("emf demo"); book.setPage(123); book.setWriter(writer);//只是在book端执行了set操作 List<Book> books=writer.getBooks();//在writer端依然能够遍历到book for(Book b:books){ System.out.println(b.getTitle()); }
虽然我们只是在book端执行了setWriter方法,而没有在writer端执行添加book的方法,但是在writer端依然能够遍历到Book对象。
聚合引用:
所谓聚合引用,就是一个对象是另一个对象的容器;比如上面的Library和Book,Library便是Book的容器。
在EMF中,容器和它所包含的对象存储在同一资源文件中,因此在加载的时候不需要使用代理机制。
在聚合引用中,每个对象只能有一个容器,因此在将一个对象加入到某个容器之前,要将该对象从现在的容器中移除出去。为了实现该功能,EObjectImpl类中设计了一个成员变量eContainer用来表示实体类对象的容器,这样我们就可以通过book.eContainer()方法来得到Library对象。
注:EMF所生成的变量或方法都会含有@generated标注,当执行regenerate操作时EMF只会覆盖含有@generated标注的方法,而自己手工添加的方法不会被覆盖。
下一篇将会讲解EMF所生成的适配器类。
相关文章推荐
- EMF学习笔记2——模型适配器类
- EMF学习笔记5——模型变动通知
- EMF学习笔记6——模型验证
- 微软CodeDom模型学习笔记(一)
- 声学模型学习笔记(五) SDT(MMI/BMMI/MPE/sMBR)
- 学习笔记之TCP/IP协议分层与OSI參考模型
- 通用模型之-party model 学习笔记
- 机器学习实战笔记(3.2)-朴素贝叶斯算法(贝努力模型代码实现)
- Latent Semantic Analysis (LSA) 模型 学习笔记
- 计算广告学习笔记1.2 广告的基础知识-广告的有效性模型
- Java虚拟机学习笔记(1)——Java虚拟机内存模型
- CUDA学习笔记之Tesla图形与计算架构和通用计算模型
- 学习《Linux设备模型浅析之驱动篇》笔记(一)
- OSG学习笔记2:地形构建和模型加载
- js学习笔记(十四)事件处理模型
- CSS学习笔记:盒模型
- 【Hibernate学习笔记】软件的模型
- 【Unity 3D】学习笔记四十七:实例——观察模型
- 学习笔记之HMM模型
- Tensorflow学习笔记-构建网络模型