讓工作更輕鬆——EA類圖與代碼同步

    進入主題之前,先說一下ea工具:EA——Enterprise Architect,是一種建模工具,想了解請點解 這裏 


    隨着能力的提升,現在做的項目,都要求先畫類圖,再敲代碼,但是每次畫圖後,在敲代碼起初,還跟圖對應着呢,到後來,發現圖中有不合適的地方,然後就把圖改一下,再敲代碼,但是圖中錯誤太多的話,就懶得再去改圖了,直接修改代碼了。這樣時間一長,圖就算廢棄了。開發完了,態度好一點的人,會用代碼去生成一下圖去交差,有的乾脆不管了,結果給同一項目組其他同事的工作造成了很大的影響。當然我說的這種情況在小公司中存在的比較多。當然我們在自學的時候,也會遇到這種情況。


    如何解決這一問題呢?
    從根本上說,當然是分析到位,畫圖時考慮周全,程序員要嚴格的按圖跟文檔去編碼。不能私自更改代碼。如需更改,需要將建議提交到項目經理那去審覈,由項目經理去修改。當然好多公司或者個人不會按照這些步驟走。畢竟改過來改過去,會浪費很多時間。所以讓圖和代碼同步,即可解決這一問題。


    先說思路吧:我這裏用到的是EA和VS2010,用EA畫類圖,然後生成代碼框架。在VS項目中添加生成的代碼,然後在VS中修改代碼,可以在EA中通過逆向代碼工程更新原來的類圖。


    簡單的演示一下:
    首先創建一個項目,我這裏創建的是控制檯應用程序:




然後在EA中畫一個類圖



在右鍵,選擇生成代碼:(因爲我這個是單個類,所以直接在類上選擇生成代碼,如果你類圖中類比較多,可以在上面那個類似文件夾的圖標上,選擇生成代碼)

選擇項目文件夾下,並選對相對應語言。我這裏用的是C#。點擊生成即可。如圖:

這樣在項目文件夾下,就看見多了一個Human.cs文件

現在這個圖跟代碼就已經建立的關係,因爲EA中集成了代碼編輯器,所以我們可以通過在類上右鍵,選擇查看源代碼:

就可以打開源代碼了:



然後在vs項目中,添加上剛生成的cs,



這樣,在vs項目中,就多了一個Human類:



打開看一下,由圖直接生成的代碼:


  1. ///////////////////////////////////////////////////////////  
  2. //  Human.cs  
  3. //  Implementation of the Class Human  
  4. //  Generated by Enterprise Architect  
  5. //  Created on:      23-八月-2012 17:18:28  
  6. //  Original author: Admin  
  7. ///////////////////////////////////////////////////////////  
  8.   
  9.   
  10.   
  11.   
  12. namespace Human {  
  13.     /// <summary>  
  14.     /// <b>學生類</b>  
  15.     /// <b>包括3個字段:name,age,sex</b>  
  16.     /// <b>添加對應的3個屬性Name,Age,Sex</b>  
  17.     /// <b>2個方法:</b>  
  18.     /// <b>構造方法和Print方法</b>  
  19.     /// </summary>  
  20.     public class Human {  
  21.   
  22.         /// <summary>  
  23.         /// 年齡  
  24.         /// </summary>  
  25.         private int age;  
  26.         /// <summary>  
  27.         /// 姓名  
  28.         /// </summary>  
  29.         private string name;  
  30.         /// <summary>  
  31.         /// 性別  
  32.         /// </summary>  
  33.         private string sex;  
  34.   
  35.         public Human(){  
  36.   
  37.         }  
  38.   
  39.         ~Human(){  
  40.   
  41.         }  
  42.   
  43.         public virtual void Dispose(){  
  44.   
  45.         }  
  46.   
  47.         /// <summary>  
  48.         /// 構造函數  
  49.         /// </summary>  
  50.         /// <param name="name">姓名</param>  
  51.         /// <param name="age">年齡</param>  
  52.         /// <param name="sex">性別</param>  
  53.         public Human(string name, int age, string sex){  
  54.   
  55.         }  
  56.   
  57.         /// <summary>  
  58.         /// 年齡  
  59.         /// </summary>  
  60.         public int Age{  
  61.             get{  
  62.                 return age;  
  63.             }  
  64.             set{  
  65.                 age = value;  
  66.             }  
  67.         }  
  68.   
  69.         /// <summary>  
  70.         /// 姓名  
  71.         /// </summary>  
  72.         public string Name{  
  73.             get{  
  74.                 return name;  
  75.             }  
  76.             set{  
  77.                 name = value;  
  78.             }  
  79.         }  
  80.   
  81.         /// <summary>  
  82.         /// 輸出學生信息  
  83.         /// </summary>  
  84.         public void Print(){  
  85.   
  86.         }  
  87.   
  88.         /// <summary>  
  89.         /// 性別  
  90.         /// </summary>  
  91.         public string Sex{  
  92.             get{  
  93.                 return sex;  
  94.             }  
  95.             set{  
  96.                 sex = value;  
  97.             }  
  98.         }  
  99.   
  100.     }//end Human  
  101.   
  102. }//end namespace Human  




現在代碼和圖算是徹底可以同步了。當我們在VS中修改代碼後,在EA中,選中相應的類,右鍵選擇|“代碼同步”,即可把代碼中修改的部分,同步到類圖中。
比如我們在代碼中添加一個address字段和屬性,並在構建函數和Print方法中添加內容:
address字段和屬性:
  1. /// <summary>  
  2. /// 住址  
  3. /// </summary>  
  4. private string address;  
  5. /// <summary>  
  6. /// 住址  
  7. /// </summary>  
  8. public string Address  
  9. {  
  10.     get  
  11.     {  
  12.         return address;  
  13.     }  
  14.     set  
  15.     {  
  16.         name = value;  
  17.     }  
  18. }  

構建函數和Print方法:
  1. /// <summary>  
  2. /// 構造函數  
  3. /// </summary>  
  4. /// <param name="name">姓名</param>  
  5. /// <param name="age">年齡</param>  
  6. /// <param name="sex">性別</param>  
  7. public Human(string name, int age, string sex){  
  8.           this.name = name;  
  9.           this.age = age;  
  10.           this.sex = sex;  
  11. }  
  12.   
  13.       /// <summary>  
  14.       /// 輸出學生信息  
  15.       /// </summary>  
  16.       public void Print()  
  17.       {  
  18.           System.Console.WriteLine("我叫 " + name + "," + sex + ",年方" + age);  
  19.       }  




然後在EA中,右鍵Human,選擇“代碼同步”,點擊“是”:
  

  
再看看類的效果:
 
已經成功的更新上去了。
當我們在修改類圖後,選擇修改後的類,再次生成代碼,即可更新原來的代碼。
現在我們在Human類中添加一個telphone及對應屬性:


右鍵生成代碼後的源碼:

  1. ///////////////////////////////////////////////////////////  
  2. //  Human.cs  
  3. //  Implementation of the Class Human  
  4. //  Generated by Enterprise Architect  
  5. //  Created on:      23-八月-2012 17:23:58  
  6. //  Original author: Admin  
  7. ///////////////////////////////////////////////////////////  
  8.   
  9.   
  10.   
  11.   
  12. namespace Human {  
  13.     /// <summary>  
  14.     /// <b>學生類</b>  
  15.     /// <b>包括5個字段:name,age,sex,address,telphone</b>  
  16.     /// <b>添加對應的3個屬性Name,Age,Sex,Address,Telphone</b>  
  17.     /// <b>2個方法:</b>  
  18.     /// <b>構造方法和Print方法</b>  
  19.     /// </summary>  
  20.     public class Human {  
  21.   
  22.         /// <summary>  
  23.         /// 年齡  
  24.         /// </summary>  
  25.         private int age;  
  26.   
  27.         /// <summary>  
  28.         /// 姓名  
  29.         /// </summary>  
  30.         private string name;  
  31.   
  32.         /// <summary>  
  33.         /// 性別  
  34.         /// </summary>  
  35.         private string sex;  
  36.   
  37.         /// <summary>  
  38.         /// 住址  
  39.         /// </summary>  
  40.         private string address;  
  41.         /// <summary>  
  42.         /// 電話  
  43.         /// </summary>  
  44.         private int telphone;  
  45.   
  46.         /// <summary>  
  47.         /// 住址  
  48.         /// </summary>  
  49.         public string Address  
  50.         {  
  51.             get  
  52.             {  
  53.                 return address;  
  54.             }  
  55.             set  
  56.             {  
  57.                 name = value;  
  58.             }  
  59.         }  
  60.   
  61.         public Human(){  
  62.   
  63.         }  
  64.   
  65.         ~Human(){  
  66.   
  67.         }  
  68.   
  69.         public virtual void Dispose(){  
  70.   
  71.         }  
  72.   
  73.         /// <summary>  
  74.         /// 構造函數  
  75.         /// </summary>  
  76.         /// <param name="name">姓名</param>  
  77.         /// <param name="age">年齡</param>  
  78.         /// <param name="sex">性別</param>  
  79.         public Human(string name, int age, string sex){  
  80.             this.name = name;  
  81.             this.age = age;  
  82.             this.sex = sex;  
  83.         }  
  84.   
  85.         /// <summary>  
  86.         /// 年齡  
  87.         /// </summary>  
  88.         public int Age{  
  89.             get{  
  90.                 return age;  
  91.             }  
  92.             set{  
  93.                 age = value;  
  94.             }  
  95.         }  
  96.   
  97.         /// <summary>  
  98.         /// 姓名  
  99.         /// </summary>  
  100.         public string Name{  
  101.             get{  
  102.                 return name;  
  103.             }  
  104.             set{  
  105.                 name = value;  
  106.             }  
  107.         }  
  108.   
  109.         /// <summary>  
  110.         /// 輸出學生信息  
  111.         /// </summary>  
  112.         public void Print(){  
  113.             System.Console.WriteLine("我叫 "+name+","+sex+",年方"+age);  
  114.         }  
  115.   
  116.         /// <summary>  
  117.         /// 性別  
  118.         /// </summary>  
  119.         public string Sex{  
  120.             get{  
  121.                 return sex;  
  122.             }  
  123.             set{  
  124.                 sex = value;  
  125.             }  
  126.         }  
  127.   
  128.         /// <summary>  
  129.         /// 電話  
  130.         /// </summary>  
  131.         public int Telphone{  
  132.             get{  
  133.                 return telphone;  
  134.             }  
  135.             set{  
  136.                 telphone = value;  
  137.             }  
  138.         }  
  139.   
  140.     }//end Human  
  141.   
  142. }//end namespace Human  




我們發現當初修改的構造函數和Print方法中的源碼部分,並沒有被刪除。這說明,圖只對代碼進行了更新,而不是覆蓋操作。


演示就到這裏。


    通過剛纔的演示,我們可以清楚的看到圖和代碼的同步,不再是那麼遙不可及。我們不用再爲了改代碼而改圖了。可以節省大量的時間。

   =======================================================================================

   我在演示的時候是一個文件,但是在實際項目中,肯定是用等多個文件。有博友問我怎麼辦,我就再補充一下吧。

   拿我的一個小項目做實驗:包圖,類圖如下:

  

   生成代碼時,如果你第一次生成源代碼,那麼可以在整個類視圖上右鍵,“代碼工程”->“生成源代碼”。這樣會爲所有的圖生成。如果你在修改某個包中的類後,用圖去更新代碼時,你可以右鍵這個包,選擇“代碼工程”->“生成源代碼”,效果是一樣的。下面這幅圖是在類視圖上面生成代碼的截圖。

 

   在對話框中的標題中,可以看出“根據包生成源碼”。這裏面也會帶有命名空間。在同步衝突中,選擇“同步模型和代碼”。然後勾選自動生成文件,並選擇你的項目路徑(同單個文件操作)。如果你的包圖中還有子包,那麼你需要勾選“包括所有子包的表”。生成即可。

 

這就是生成的效果了:

 

   而用代碼更新類圖時,如果你想同步全部類圖,那麼在類視圖上右鍵,“代碼工程”->“導入源文件目錄”。如果你只想更新一個包,那麼在包上面右鍵,操作都是一樣的。我這裏選擇的是IDAL包(現在附加的這個項目使用VB.NET做的)。

 

   在“導入源碼”對話框中,選擇代碼所在的根目錄(這個在更新某個包的時候一定要看清楚了,否則就會把其他包的類導入到這個包中)。文件類型選正確了。包結構選擇“爲每個目錄生成包”,否則可能會出現你不想看到的效果。同步類型選擇“同步已存在的類”。如果你選擇的覆蓋,那麼其他類與被更新的類之間的聯繫都會被刪除,而且在時序圖中被更新的類的對象,也會變爲空白。所以一定要選擇同步。刪除,根據實際情況而定吧。如果代碼中刪除了某些類,那麼在更新類圖 時,會根據你的選擇,做出對應的操作。

 

   好了,對於項目中多個文件的操作,就說這麼多。紙上得來終覺淺,絕知此事要躬行,所以還是需要大家實際實驗一下才知道。

=======================================================================================


    當然,這個方案,只是一個代碼和圖脫節的補救措施。最重要的還是在前期儘可能的設計好,在編碼時嚴格按照圖和文檔進行編碼,纔不會出現那代碼與圖的脫節現象。

    回首一望,才發現,其實我們總是在有意無意的遵循着“簡單原理”,也正是由於“簡單原理”,我們的效率纔會不斷的提高,我們纔會不斷的進步。
    


轉載請說明出處http://blog.csdn.net/xiaoxian8023/article/details/7901206

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章