在八进制的中讲述了从模型到应用程序的生成过程。我通过类似的方法生成了一个应用程序。
代码生成后,我就想看看EMF为我生成了什么样的代码。我如果需要修改的话该如何修改。
我的“Hellow world”是采用的“Using EMF”文中的模型。
根据这个模型建立了一个EMF Model:
根据这个模型生成model class的结构如下图所示:
从图中我们可以看到有三个包:
他们分别是:family,family.impl和family.util。
family和family.impl包之间的差别就是一个是Interface,另外一个是这些Interface的实现。
我们先来看看我们模型中出现过的类:
Family,FamilyTree,Female,Male以及Individual。
由于我是采用Annotated Java的方式生成的模型。所以在family包中的代码并没有太多的变化。
/**
* Return the father
* @return the father
* @model
*/
Male getFather();
/**
* Sets the value of the '{@link com.jet.swt.emf.family.Family#getFather <em>Father</em>}' reference.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param value the new value of the '<em>Father</em>' reference.
* @see #getFather()
* @generated
*/
void setFather(Male value);
他只是为我提供了Set方法。接口的继承也没有做修改。但是他对应的实现类就有了很多变化。
首先从类的申明来看:
public class FamilyImpl extends EDataObjectImpl implements Family {
我们可以看到我们的FamilyImpl是从EdataObjectImpl类继承而来。处于好奇我有在Hiberarchy中打开他的继承关系看了一下。
这里有一张图可以清晰的说明这个继承关系的职能。
我例子中的Business Layer是FamilyImpl类。
这样我们的就可以不写一行代码就可以使我们的对象具有Notification/Common的功能(关于Notification和Common的功能到底是怎样的,我会在后续的学习笔记中记下来。呵呵,是不是很爽啊)。另外在《Eclipse Modeling Framework: A Developer's Guide》一书的第二章也有提到这部分的内容,不过由于他讲解的EMF的版本比较老和我现在使用的版本有点出入,不过基本的功能还是讲到了。
好了,看完申明我们就来继续往下看吧。
在Family下面有三个属性,father,mother和children。
EMF给我们生成的对应的代码为:
protected Male father = null;
/**
* The cached value of the '{@link #getMother() <em>Mother</em>}' reference.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getMother()
* @generated
* @ordered
*/
protected Female mother = null;
/**
* The cached value of the '{@link #getChildren() <em>Children</em>}' containment reference list.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getChildren()
* @generated
* @ordered
*/
protected EList children = null;
以及一些get和set方法。
对于set方法中除了基本的赋值以外还加上了向所有对这次变动感兴趣观察者发送一个变更消息:
public void setFather(Male newFather) {
Male oldFather = father;
father = newFather;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, FamilyPackage.FAMILY__FATHER, oldFather, father));
}
对于get方法要分基本类型还是对象这两种类型来处理。
如果是基本类型,直接返回就好了。
如:
public String getName() {
return name;
}
如果是对象的话就有点麻烦了。先要判断该对象是否使用了代理(这一部分我还不是太清楚)如果是的话就获得他的代理对象,并判断获得代理对象是否和当前对象是否相等,如果不等就发送一个变更消息。最终返回对象(肯能是一个代理对象)。
public Male getFather() {
if (father != null && ((EObject)father).eIsProxy()) {
Male oldFather = father;
father = (Male)eResolveProxy((InternalEObject)father);
if (father != oldFather) {
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.RESOLVE, FamilyPackage.FAMILY__FATHER, oldFather, father));
}
}
return father;
}
还有其他类将在下一篇记下。
1、 Using
EMF, Author :Catherine Griffin
2、 EMF介绍系列(二、从模型生成应用程序) Author:八进制
3、 Mastering Eclipse Modeling Framework,Author:Vladimir Bacvanski(Vladimir@inferdata.com)
Petter Graff(petter@inferdata.com)
Eclipse
Modeling Framework: A Developer's Guide Author:Frank Budinsky, David Steinberg, Ed Merks, Raymond Ellersick, Timothy J. Grose