使用Rational進行C++轉換的技巧

  UML 是一個通用的語言。使用 IBM? Rational Software Architect 和 IBM Rational Systems Developer,您可以實現由 UML 模型向 C++ 的轉換。這篇文章討論了如何更好地控制由 UML 向 C++ 轉換而生成的 C++ 代碼。文章分成幾個章節,各部分相對獨立,分別介紹了一種技巧。您可以根據需要選讀,而不必遵循特定的次序。
  應用 C++ Transformation 概要文件以實現 C++ 結構的建模
  在統一建模語言 UML 和某特定領域之間建立聯系的標准方法是使用 UML PRofile(UML 概要文件)。UML 概要文件可以爲已有 UML 元素定義附加語義和特性,例如類、操作等。建模 C++ 特定元素的時候,如 結構體、聯合體、名字空間 等,需要用到 UML 概要文件。在 Rational Software Architect 和 Rational Systems Developer 使用 C++ Transformation profile 實現 UML 向 C++ 的轉換,這個概要文件在 UML 模型中的應用如下所示。
  在 Project EXPlorer 中選擇概要文件將要應用的 UML 模型。
  在 Project Explorer 保持模型是選中狀態,轉換到 Properties View,單擊 Profiles 選項卡。
  如圖1所示,單擊 Add Profile 按鈕。
  圖1. 將 UML 運用到 C++ Transformation 概要文件
  
使用Rational進行C++轉換的技巧

  如圖2所示,從 Deployed Profile 下拉列表框中選擇 C++ Transformation。
  圖2. 選擇 C++ Transformation
  
使用Rational進行C++轉換的技巧

  導入 C++ 類型庫
  UML 提供了一組已定義好的類型,有 Boolean, Integer, String 和 UnlimitedNatural。而大多數的編程語言,包括C++,提供了更爲豐富的基本類型。在 C++ 中建模的時候,您可能經常需要使用 C++ 預定義的原始類型(比如,將一個類型賦給某個屬性、參數、操作返回類型,等)。To import the C++ model library that is shipped with the C++ Transform,在 Project Explorer 中右鍵單擊UML模型,然後選擇 Import Model Library,如下圖3所示。
  圖3. 導入 C++ 類型庫
  
使用Rational進行C++轉換的技巧

  如圖4所示,從 Deployed Library 列表中選擇 C++ Types。
  圖4. 導入 C++ Type Library
  
使用Rational進行C++轉換的技巧

  在模型中創建 C++ 名字空間
  本章節講述如何在 UML 模型中爲 C++ 名字空間建模。在 C++ 中創建一個名字空間時,需要將 cpp_namespace 原型應用在 UML 包。在 UML 向 C++ 轉換的過程中,一個 UML 包默認被映射成一個文件夾。假如想要將 UML 包映射成名字空間,而不是文件夾,那麽,您需要應用 cpp_namespace 原型,然後設置 NamespaceName 的屬性,使其與指定的名字空間相關聯。這個 stereotyped UML 包下所有的 類、結構、枚舉 (以及其它)生成代碼之後,都將包括在這個名字空間中。
  您可能想知道爲什麽名字空間不能直接采用 stereotyped 包的名稱。這是爲了支持 C++ 匿名的名字空間建模。所以,假如您將 NamespaceName 屬性設置爲空,那麽,該名字空間就會被認爲是匿名的。
  建模 C++ typedefs
  要建模 C++ typedef,需要創建一個 UML 類並在其上應用 cpp_typdef 原型。該原型提供了以下屬性/值:
  arrayDimensions
  ImplementationType
  qualifier
  想要創建一個類型定義,比如 typedef int const IntMatrix100_20_t [10][20];,首先創建一個 UML 類 IntMatrix100_20_t,然後應用 cpp_typedef 原型。如圖5所示,設置該原型的屬性。
  圖5. 建立一個 C++ 類型定義
  
使用Rational進行C++轉換的技巧

  在將 typedef 定義與概要文件中提供的屬性相關聯的過程中,您可能會考慮到以下方式: typedef
  創建多維數組屬性
  在本節中,您將會學到如何爲一個大小爲[10][20][30]的三維數組定義屬性。在 Project Explorer 中選擇需要賦給多維數組的屬性。在 Properties 視圖中,單擊 Stereotypes 選項卡,然後單擊 Apply Stereotypes 按鈕,並選擇 cpp_type 原型。這個原型提供了以下屬性/值:
  arrayDimensions
  InitializerKind
  isAuto
  isMutable
  isRegister
  isVolatile
  qualifier
  如圖6所示,在 arrayDimensions Value 處,指定 [10][20][30]。這樣,在源代碼中就會生成維度屬性爲[10][20][30]的數組。
  圖6. 設置 Multidimensional Attributes
  將一個方法的形參設置爲常量
  這個技巧的原理同上(前面提到的定義多維數組)。在 Project Explorer 中選擇預備設置爲 const 的參數。單擊 Apply Stereotypes 按鈕並選擇 cpp_type 原型。該類型提供了以下屬性/值:
  arrayDimensions
  InitializerKind
  isAuto
  isMutable
  isRegister
  isVolatile
  qualifier
  這些屬性都是可能用得到的,但暫時只介紹 qualifier 屬性。在 qualifier 的 Value 處,輸入 const (如 圖5 所示)。這樣,當轉換執行的時候,將在源代碼中爲選定的參數生成帶有常量修飾符的函數簽名。
  注: 請確保輸入的值是有效的。假如輸入錯誤,則會導致編譯失敗,您需要在再次運行轉換之前修正錯誤。
  另外,cpp_type 原型也適用于類的屬性。但是,生成一個常量屬性的更簡單的方法是將屬性標明爲 Read Only。
  將整個方法聲明爲常量
  假設您想要將一個方法聲明爲常量,以便在生成的代碼中帶有 const 要害字: )int Operation1(MyType Parameter1 const;。您需要在 Properties 視圖的 General 選項卡中選擇 Query 修飾符。這裏,不需要應用原型。
  圖7. 創建一個常量方法
  
使用Rational進行C++轉換的技巧

  給一個方法增加異常處理
  Exceptions 是 UML 中重要的類,它在建模過程中不需要使用概要文件。爲了簡化並推廣建模, UML to C++ Transformation 使用了普遍適用的 UML 屬性,而不是概要文件。要生成一個 throw 子句,比如 int Operation1() throw ( MyType);,您首先需要爲操作創建一個參數,然後設置其 Is Exception 屬性爲 true。
  在轉換過程中,參數名是可以被忽略的,但最好還是定義一個合適的名稱(以備異常抛出時正確提示)。圖8顯示了如何將參數的 Is Exception 屬性設置爲 true。
  圖8. 設置某方法的 throw 類型
  
使用Rational進行C++轉換的技巧

  控制生成的代碼中的 include 聲明
  UML to C++ Transformation 可以自動生成恰當的 include 聲明。 然而,您可能想要根據需要生成更合適的 include 聲明。例如,已確定要使用本地方法體的某個類型變量,因此,想要生成包括在文件中的 include 聲明建模時,您可能需要創建兩個類之間的依靠,然後將 cpp_dependency 原型應用在依靠。這個原型和名爲 IsInclusionInHeader 的屬性一起出現,該屬性值默認爲 false。假如需要將 include 聲明包括在生成的文件體中,請將這個屬性值設爲 false;假如需要將 include 聲明生成在頭文件中,那麽,可以不設置依靠的 cpp_dependency 原型,也可以應用原型並將 IsInclusionInHeader 屬性值設爲 true。
  使用文件級別得重用保護部分
  假如要使用標准庫的類型,或者一些源代碼的其它庫,您需要在模型中將這些類型設置爲普通的字符串。例如,假如要將一個屬性聲明爲整型,您需要在模型中指定它的類型爲 vector 轉換時,將會把這些類型當成原始類型,並且不會生成任何 include 聲明或其它聲明。因此,您需要將這些都明確地包含進源文件中。
  比如,對于 vector 類型,您應當明確地將 include 聲明放置在源代碼中,比如 #include 。如列表1所示,在應用 UML 向 C++ 的轉換過程中,每個生成的文件都一字不漏地包含一些段落的內容。請注重 //TODO: Add definitions that you want preserved。您添加到 Begin section 和 End section 中的任何內容都將被保存下來。請在此處添加聲明,比如這裏的 #include 。
  列表1. 類 Car 所生成代碼
  
  #ifndef CLASS1_H
  #define CLASS1_H
  //Begin section for file Class1.h
  //TODO: Add definitions that you want preserved
  //End section for file Class1.h
  #include "MyType.h"
  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
  class Class1
  {
  //Begin section for Class1
  //TODO: Add attributes that you want preserved
  //End section for Class1
  public:
  //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
  int Operation1()const throw ( MyType);
  }; //end Class Class1
  #endif
  刪除類級別得重用保護部分
  請注重,在前面列表1的代碼中,有一段 //Begin section for Class1 ... //End section for Class1 ,您可以將 C++ 中所有不能建模的聲明保存在這裏。返回 UML to C++ Transformation 時,不會覆蓋這段聲明。假如您不需要這一聲明出現在生成的代碼中,可以選擇刪除。但是,刪除之後,即使再次運行 UML to C++ Transformation,這些聲明也不會重新生成。
  假如不需要,可以刪除如列表2所示的段落,那麽刪除之後不能夠重新生成。假使想要恢複這些聲明,您就需要手動地進行插入。
  列表2. 類 Car 生成的代碼
  
  ...
  //Begin section for Class1
  //TODO: Add attributes that you want preserved
  //End section for Class1
  ...
  不修改 UML 模型的情況下,改變生成包的名稱。
  要改變包的名稱,請雙擊打開轉換配置文件。如圖9所示,單擊 Mapping 選項卡,選擇 Enable mapping。
  圖9. 使用映射模型
  
使用Rational進行C++轉換的技巧

  單擊 New 按鈕,創建一個默認的映射模型,賦給一個適合的名稱。單擊 Edit Mapping 按鈕,出現如圖10所示的對話框。
  圖10. 編輯映射模型
  
使用Rational進行C++轉換的技巧

  假使您正進行到如圖11所示的 UML 模型。假如沒有映射模型,那麽 Date 類將會生成在一個名爲 Package1 的文件夾內。然而,假如您想要將 Package1 生成爲 Folder1,那麽需要使用映射模型。浏覽映射模型,找到 Package1,然後在向導底端的 Mapped Name 編輯框輸入 Folder1。這樣,在生成的代碼中,Date 類就生成在名爲 Folder1 的文件夾內了。
  圖11. 您正在操作的 UML 模型
  在同一個文件裏生成多個類
  在映射模型中,假如您想將一個 UML 類映射爲另外的名稱,您需要改變其將要生成文件的名稱,而不是類名。默認情況下,頂級類將生成一個與類名相同名稱的文件。因此,對于一個名爲 MyClass 的 UML 類,UML 向 C++ 的轉換將會生成文件 MyClass.h 和 MyClass.cpp。
  但是,在使用映射模型的時候,您也可以選擇生成與原類名不同名稱的文件。比如,您可以改變 UML 包的名稱,生成另外命名的文件夾;您也可以將一個 UML 類映射爲另外命名的文件。類的名稱並不受映射模型的影響。因此,要想在一個文件中生成多個類,您所需要做的僅僅是在映射模型中爲它們指定相同的目標名稱。