2012年10月16日火曜日

MindmapModelingと集合知(10) - トレイト

前回はマインドマップではなく、通常の仕様書ライクな文書によるSimpleModeler DSLであるSmartDox DSLを紹介しました。

SmartDox DSLを用いることで、マインドマップモデルでは難しかった本格的なシステム開発をターゲットにしたコード生成を行うことができます。

さて、SmartDox DSLでモデリングを始めてみると、あるモデル要素が無性に使いたくなってきました。そのモデル要素とは「トレイト」です。

ここで言うトレイトはScalaが提供しているミックスイン用のクラス断片で、通常のクラス継承の機能を緩めることで、多重継承的なモデリングを可能にします。scalaプログラミングではトレイトを用いたCakeパターンが非常に便利ですが、これをオブジェクト・モデリングの段階でも使いたいと考えたわけです。

そこで、ここ数日SimpleModelerにトレイトを追加する拡張を行なっていたのですが、何とか動くようになりました。

以下の文書がトレイトを用いたSmartDox DSLです。

  1. #+title: Table  
  2.   
  3. SmartDox DSLを使って記述したモデルの  
  4. サンプル文書です。  
  5.   
  6. 文書でサンプルモデルの定義をします。  
  7. 本来は文書中の仕様記述の文書は  
  8. 定義するモデルに対するものになります。  
  9.   
  10. しかし、この文書ではSmartDox DSLの記述例として  
  11. SmartDox DSL文法の説明を記述することにします。  
  12.   
  13. * サンプル文書の目的  
  14.   
  15. このサンプル文書は表を中心にしてクラス定義するサンプルです。  
  16.   
  17. 表を中心にトレイトを使ったモデリングのサンプルです。  
  18.   
  19. * 特色  
  20.   
  21. ** Master  
  22.   
  23. ** Transaction  
  24.   
  25. ** LogicalDeletable  
  26.   
  27. ** ImageHolder  
  28.   
  29. ** Tagable  
  30.   
  31. * 登場人物  
  32.   
  33. ** 顧客  
  34.   
  35. #+caption: 性質一覧  
  36. | 項目 | 値                                          |  
  37. |------+---------------------------------------------|  
  38. | 特色 | Master,LogicalDeletable,ImageHolder,Tagable |  
  39.   
  40. #+caption: 属性一覧  
  41. | 名前   | 型     | カラム  | SQL型        |  
  42. |--------+--------+---------+--------------|  
  43. | 顧客ID | token  | ID      | CHAR(16)     |  
  44. | 名前   | token  | NAME    | VARCHAR(64)  |  
  45. | 住所   | string | ADDRESS | VARCHAR(256) |  
  46.   
  47. * 道具  
  48.   
  49. ** 商品  
  50.   
  51. #+caption: 性質一覧  
  52. | 項目 | 値                                          |  
  53. |------+---------------------------------------------|  
  54. | 特色 | Master,LogicalDeletable,ImageHolder,Tagable |  
  55.   
  56. #+caption: 属性一覧  
  57. | 名前   | 型    | ID | カラム | SQL型       |  
  58. |--------+-------+----+--------+-------------|  
  59. | 商品ID | token | ○ | ID     | CHAR(16)    |  
  60. | 名前   | token |    | NAME   | VARCHAR(32) |  
  61. | 定価   | money |    | PRICE  | LONG        |  
  62.   
  63. * 出来事  
  64.   
  65. ** 購入  
  66.   
  67. #+caption: 性質一覧  
  68. | 項目 | 値                           |  
  69. |------+------------------------------|  
  70. | 特色 | Transaction,LogicalDeletable |  
  71.   
  72. #+caption: 特性一覧  
  73. | 特性 | 名前   | 型    | 多重度 | 派生        | カラム      | SQL型    |  
  74. |------+--------+-------+--------+-------------+-------------+----------|  
  75. | ID   | 購入ID | token |        |             | ID          | CHAR(16) |  
  76. | 属性 | 日付   | date  |        |             | DATE        | DATE     |  
  77. | 関連 | 顧客   | 顧客  |      1 |             | CUSTOMER_ID | CHAR(16) |  
  78. | 属性 | 顧客名 | token |        | 顧客.名前   |             |          |  
  79. | 関連 | 商品   | 商品  |      1 |             | GOOD_ID     | CHAR(16) |  
  80. | 属性 | 数量   | int   |        |             | AMOUNT      | INT      |  
  81. | 属性 | 商品名 | token |        | 商品.名前   |             |          |  
  82. | 属性 | 単価   | money |        | 商品.定価   |             |          |  
  83. | 属性 | 総額   | money |        | 数量 * 単価 |             |          |  

以下の5つのトレイトを定義しています。例題なので中身は定義していませんが、以下のような用途を想定しています。

Master
マスターテーブル
Transaction
トランザクションテーブル
LogicalDeletable
論理削除
ImageHolder
イメージと関連付け
Tagable
タグと関連付け

ポイントとなるのは、顧客はMaster, LogicalDeletable, ImageHolder, Tagable、商品はMaster, LogicalDeletable, ImageHolder, Tagable、購入はTransaction, LogicalDeletableといったように必要な特色(トレイト)を自由にミックスインすることができる点です。

クラス図

上記のDSLからSimpleModelerを使って以下のクラス図を生成することができます。




実装

モデリング時にトレイトを使う場合、Scalaでは特に問題なくそのまま実現できるのは明らかです。それでは、JavaやRDBMSの場合はどうなるでしょうか。

Java

Javaの場合は、複数のトレイトを合体させた実装をクラスとして生成し、トレイトに対応するインタフェースとimplementsしておけばよいでしょう。手動でトレイト相当を実装すると大変ですが、コード生成であれば特に難しかったり煩雑だったりするところはありません。

RDBMS

RDBMSのテーブルは、単純に元のテーブル定義にトレイトを合体させたテーブルを生成すればよいでしょう。これもコード生成であれば難しいところはありません。

以上のようにトレイトはモデリング上も有効な上に、コード生成を前提にすればJavaやRDBMSといった既存のプラットフォームでも問題なく展開することができます。

UML時代には存在していなかったトレイトですが、SimpleModelerを使ったモデル駆動開発では非常に有効に使えそうです。

0 件のコメント:

コメントを投稿