在八進制的中講述了從模型到應(yīng)用程序的生成過程。我通過類似的方法生成了一個應(yīng)用程序。
代碼生成后,我就想看看EMF為我生成了什么樣的代碼。我如果需要修改的話該如何修改。
我的“Hellow world”是采用的“Using EMF”文中的模型。

根據(jù)這個模型建立了一個EMF Model:

根據(jù)這個模型生成model class的結(jié)構(gòu)如下圖所示:

從圖中我們可以看到有三個包:
他們分別是:family,family.impl和family.util。
family和family.impl包之間的差別就是一個是Interface,另外一個是這些Interface的實現(xiàn)。
我們先來看看我們模型中出現(xiàn)過的類:
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方法。接口的繼承也沒有做修改。但是他對應(yīng)的實現(xiàn)類就有了很多變化。
首先從類的申明來看:
public class FamilyImpl extends EDataObjectImpl implements Family {
我們可以看到我們的FamilyImpl是從EdataObjectImpl類繼承而來。處于好奇我有在Hiberarchy中打開他的繼承關(guān)系看了一下。
這里有一張圖可以清晰的說明這個繼承關(guān)系的職能。
我例子中的Business Layer是FamilyImpl類。
這樣我們的就可以不寫一行代碼就可以使我們的對象具有Notification/Common的功能(關(guān)于Notification和Common的功能到底是怎樣的,我會在后續(xù)的學(xué)習(xí)筆記中記下來。呵呵,是不是很爽啊)。另外在《Eclipse Modeling Framework: A Developer's Guide》一書的第二章也有提到這部分的內(nèi)容,不過由于他講解的EMF的版本比較老和我現(xiàn)在使用的版本有點出入,不過基本的功能還是講到了。
好了,看完申明我們就來繼續(xù)往下看吧。
在Family下面有三個屬性,father,mother和children。
EMF給我們生成的對應(yīng)的代碼為:
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方法中除了基本的賦值以外還加上了向所有對這次變動感興趣觀察者發(fā)送一個變更消息:
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;
}
如果是對象的話就有點麻煩了。先要判斷該對象是否使用了代理(這一部分我還不是太清楚)如果是的話就獲得他的代理對象,并判斷獲得代理對象是否和當(dāng)前對象是否相等,如果不等就發(fā)送一個變更消息。最終返回對象(肯能是一個代理對象)。
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介紹系列(二、從模型生成應(yīng)用程序) 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