MDA之路

          MDA,UML,XML,Eclipse及Java相關的Blog
          posts - 53, comments - 494, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          MDA中模型的存儲、表現與轉換

          Posted on 2006-02-13 21:08 wxb_nudt 閱讀(3919) 評論(4)  編輯  收藏 所屬分類: 技術雜談

          MDA中模型的存儲、表現與轉換

          最近一些朋友在我的blog上面留言或者給我寫email討論一些問題,本文希望能夠一起解答他們的一些疑問,同時也整理一下自己的思路。

          MDA是以模型為中心的,模型是其基本元素,所以關于模型的存儲、查詢、表現和轉換是對于基本元素的操作。OMG已經有一些既定規范或者正在制訂的規范是用來討論這些問題的。例如XMI規范規定了模型的存儲格式、QVT規范(正在制訂中,已經有一個初步的版本)是規定模型的查詢、視圖和轉換的。最近的QVT規范對于模型的查詢尚未涉及,因此本篇中也不討論模型查詢。重點總結一下模型的存儲、表現(視圖)和轉換。并力所能及的舉例來說明。

          模型的存儲

          我認為模型的存儲按照其發展進程來看可以分為以下幾種:自定義格式;基于XML的自定義格式;遵守XMI的格式;可以轉換為其它格式的腳本格式;以及直接以代碼存儲的形式。

          我對于軟件建模的了解是從UML開始的,UML統一之前的各種建模方法并未研究,相信在UML統一之前,模型是沒有一個統一的存儲格式的。其必然是按照自定義的格式來存儲的。不同的建模工具是按照自己定義的格式來存儲模型,對于以下一個最簡單的模型:

          image001.gif

          一個建模工具可以這樣存儲:

          類:Bank

          屬性:name;類型:string

          連接:customers;類型:Customer

          類:Customer

          屬性:name;類型:string

          屬性:age;類型:int

          屬性sex;類型:boolean

          連接:bank;類型:Bank

          簡而言之,只要建模工具能夠識別,模型的存儲格式是沒有限制的。

          但是,這種自定義的方式顯然是有缺點的,最大的兩個確定就是不具有可交互性,不能被其它工具識別。目前的建模工具已經不使用這樣隨意的方法了。

          交互性好,能夠廣泛的被工具識別的XML技術恰好與建模技術的發展在同步進行。大概都在2000年左右,UMLXML幾乎同時達到了最高點,因此現在的建模工具使用基于XML的模型存儲格式也就不是一件意外的事情了。由于幾乎所有的建模工具都采用了XML作為模型的存儲方式,OMG特別制訂了一個XMI規范,專門規定了模型的XML存儲格式。XMI事實上是一個XML Schema,它規定了模型、對象等概念的存儲格式。

          目前很多建模工具都支持XMI2.0的存儲,例如EMF、MagicDrawRationalRose我沒有看,估計支持,因為和EMF一樣都是IBM的一母同胞)。下面是EMF的存儲格式,同樣是上面的那個模型:

          <?xml version="1.0" encoding="UTF-8"?>

          <ecore:EPackage xmi:version="2.0"

              xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

              xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="mypackage">

            <eClassifiers xsi:type="ecore:EClass" name="Bank">

              <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

              <eStructuralFeatures xsi:type="ecore:EReference" name="customer" lowerBound="1"

                  upperBound="-1" eType="#//Customer"/>

            </eClassifiers>

            <eClassifiers xsi:type="ecore:EClass" name="Customer">

              <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

              <eStructuralFeatures xsi:type="ecore:EAttribute" name="age" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>

              <eStructuralFeatures xsi:type="ecore:EAttribute" name="sex" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>

              <eStructuralFeatures xsi:type="ecore:EReference" name="bank" eType="#//Bank"/>

            </eClassifiers>

          </ecore:EPackage>

          可以看出來,EMF使用了XML1.0XMI2.0EMF的模型存儲是比較簡化的,可以人工閱讀和修改。MaigicDraw以及Rose的模型存儲則非常繁瑣,包含了眾多圖信息(所謂圖信息,就是定義了可視化模型元素的位置、大小、顏色等的信息)、自定義信息等,是不支持人工閱讀的。例如上面那個模型的MagicDraw的模型存儲文件如果不壓縮的話有174kb。

          也有一些工具使用類型于腳本的語言來定義和存儲模型,這種腳本一般都類似java語言或者idl等語言,可以方便的定義模型元素。也能夠被方便的轉換為不同工具支持的模型。例如ATL自帶的km3語言。當然,這樣總是覺得有點怪怪的。明明使用模型就是為了避免從代碼開始,但是定義模型竟然又使用了另一種代碼。上面的模型使用km3的格式如下:

          package mypackage {

          class Bank {

                     attribute name[0-1] ordered : EString

                     reference customer[1-*] ordered : Customer;

          }

           

          class Customer {

                     attribute name[0-1] ordered : EString

                     attribute age[0-1] ordered : EInt

                     attribute sex[0-1] ordered : EBoolean

                     reference bank[0-1] ordered : Bank;

          }

          }

          最后,用代碼也可以存儲模型,EMF的一種模型存儲方式就是帶有標記的java代碼來存儲模型,所以上面的模型也可以使用如下代碼存儲:

          public class Bank {

          private String name;

          private Customer customers;

          }

          public class Customer {

          private String name;

          private int age;

          private boolean sex;

          private Bank bank;

          }

          Together這樣的工具根本就把模型和代碼看成同一件事物的兩種外表,因此,用代碼做為存儲模型的格式也是自然而精確的。不過這樣也是有缺點的,就是圖信息無法保存,而且要確保代碼生成是毫無疑義的。

          模型的表現

          QVT(模型的查詢、視圖、轉換)規范中使用的是View這個術語,它的含義是模型的表現或者視圖。在最近的QVT規范中,還不支持視圖的創建和管理。但是視圖的概念類似與MVC中的視圖概念。我試著下一個定義:模型的視圖指的是對于軟件模型的某個側面在某種場景下的一種表現方式。例如,類圖是對于某個軟件的靜態結構的視圖,而對象圖是軟件運行時的某個時刻的視圖。

          視圖的另外一層含義是,如何將存儲好的模型以可視化的方式展現在用戶面前。有人說,最好的建模工具是白紙和筆,這句話也是有一定道理的。用白紙和筆可以很快的畫出可以用來交流的UML圖。此時,白紙上的UML圖就是模型的一個視圖。UML為模型的視圖提供了一組標準化的符號和概念,讓用戶可以使用不同的建模工具構建具有相同含義的軟件模型,即使它們的顏色、大小、方位以及存儲格式不同,它們指的是同樣的內涵。

          一個模型的信息只有一個,但是其表達方式是無窮的,每種表達方式都可以稱為此模型的一個視圖,它們通常是白紙上畫出的模型,或者建模工具中的圖形,或者規范的XML文件等等。

          舉例說明,上面例子模型中,其類圖是一種視圖,我們也可以規定另一種視圖如下:

          每個類用綠色的方塊表示,方塊中上部寫類名稱,中下部寫屬性名稱,屬性后面必須跟一個冒號,冒號后面是屬性的類型……

          模型的轉換

          在看透了模型存儲和視圖的本質以后,再來討論模型的轉換就比較容易了。模型的本質是什么呢?是其存儲格式還是其表現形式呢?都可以!根據其存儲格式或者視圖都可以進行模型轉換。

          最簡單的模型轉換例子就是xslt了。以XML格式存儲的模型,一個XSLT的入門者就可以寫出模型轉換的實例。

          例如我們要將上面的EMFXML存儲文件轉換一下,Bank類的name屬性名改為bankname,則使用下面的xsl文件可以轉換:

          <?xml version="1.0" encoding="UTF-8"?>

          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">

          <xsl:template match="/">

                     <xsl:apply-templates select="ecore:EPackage"/>

          </xsl:template>

          <xsl:template match="ecore:EPackage">

                     <xsl:text disable-output-escaping="yes">

          &lt;ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"

          xmlns:fo="http://www.w3.org/1999/XSL/Format"

          </xsl:text>

           name= "<xsl:value-of select="@name"/>"

           <xsl:text disable-output-escaping="yes">&gt;</xsl:text>

                     <xsl:apply-templates select="eClassifiers"/>

                     <xsl:text disable-output-escaping="yes">

                              &lt;/ecore:EPackage&gt;

                     </xsl:text>

          </xsl:template>

          <xsl:template match="eClassifiers">

                     <xsl:choose>

                              <xsl:when test="@name[. = 'Bank']">

                                       <eClassifiers xsi:type="ecore:EClass" name="Bank">

                                                 <xsl:for-each select="eStructuralFeatures ">

                                                          <xsl:choose>

                                                                   <xsl:when test="@name[. = 'name']">

                                                                             <eStructuralFeatures xsi:type="ecore:EAttribute" name="bankname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

                                                                   </xsl:when>

                                                                   <xsl:otherwise>

                                                                             <xsl:copy-of select="."/>

                                                                   </xsl:otherwise>

                                                          </xsl:choose>

                                                 </xsl:for-each>

                                       </eClassifiers>

                              </xsl:when>

                              <xsl:otherwise>

                                       <xsl:copy-of select="."/>

                              </xsl:otherwise>

                     </xsl:choose>

          </xsl:template>

          </xsl:stylesheet>

          其中<xsl:template match="ecore:EPackage">可以寫得更簡潔一點,直接使用源文件中的這個部分來代替,但是為了體現屬性的讀取功能,所以使用了xsl:value-of來讀取屬性,并填入ecore:EPackage的標記中,同時因為標記不能封閉,所以使用了xsl:text來輸出。運行這個xsl轉換源模型就可以得到目標模型。

          源模型和目標模型在EMF中的顯示如下:
          image003.gifimage004.jpg

          左邊的是源模型,右邊則是目標模型。從上面簡單的例子可以看出,模型轉換可以使用XSLT對以xml方式存儲的模型進行轉換。

          但是,以XSLT來進行模型轉換是不自然而且繁瑣的。我們需要更好的模型轉換方法。這時的一個思路就是能否把模型載入內存,然后用面向對象的方法以及語言來處理模型元素對象,然后生成目標模型。

          (撰寫中。。。)


          評論

          # re: MDA中模型的存儲、表現與轉換  回復  更多評論   

          2006-02-14 09:49 by Christine
          謝謝指點,
          關注 ing "模型的轉換"

          # re: MDA中模型的存儲、表現與轉換  回復  更多評論   

          2006-11-15 22:17 by jesse[匿名]
          View是不是還可以這樣理解,我覺得QVT中的view和SQL中的view非常相似。例如我們在數據庫中創建了一個非常復雜的table,而我們的操作又只關注這個table的某幾條數據,這樣我們就可以對我們關心的數據創建一個view。這樣我們對table的操作就可以通過view來實現。
          同樣,對于一些復雜的模型集合,我們也許只關注其中某些模型或者一些模型的某些方面,這時我們就可以建立一個這樣的"view",使我們的關注點放在這個view上

          # re: MDA中模型的存儲、表現與轉換  回復  更多評論   

          2007-11-11 19:03 by 劉玉龍
          找到專家了,請多指導.

          # re: MDA中模型的存儲、表現與轉換  回復  更多評論   

          2009-04-24 15:09 by bengle
          這個東東到底好不好用啊
          聽起來不錯
          但是JAVA WEB中用的時候只能轉成JSF的...
          期待該技術的發展
          主站蜘蛛池模板: 瓮安县| 阿坝| 唐山市| 肥乡县| 遂平县| 建阳市| 建瓯市| 丹凤县| 正镶白旗| 台南市| 昌邑市| 南江县| 平邑县| 澄江县| 正镶白旗| 六安市| 南昌市| 美姑县| 子洲县| 六盘水市| 康乐县| 吴忠市| 泸西县| 罗甸县| 保靖县| 肇州县| 康保县| 察雅县| 岗巴县| 福建省| 会昌县| 迁安市| 丹寨县| 进贤县| 永平县| 乌兰察布市| 尉犁县| 淅川县| 荥经县| 九龙城区| 济源市|