M GrammarでDSL(続き)
M GrammarでDSLを定義して使う流れを追記するとこんな感じです。
M GrammerのソースコードをMG.exeでコンパイルすると、MGXというメタファイル(ZIP形式)が出力されます。MGX.exeを使って、そのMGXイメージとDSLを与えることで、M言語のソースを出力することができます。
コマンドラインではこんな感じです。
:: DSLを定義したMGファイルからMGXイメージを出力 mg.exe /t:mgx sample.mg :: MGX.EXEにDSL(sample.movie)とイメージファイルを与える→出力はM言語のソース mgx.exe /t:M /r:sample.mgx sample.movie
生成されるM言語のコードはこんな感じです。
module sample { Movies { { Name = "Hello2009", Director = "Mike" }, { Name = "Star Sky", Director = "Unknown" }, { Name = "DogAndCat", Director = "H Miya" } } } //ただし、M.exeのコンパイルを通すためには別途Movieの宣言が必要。
最終的に生成されるSQLはこんな感じです。
insert into [sample].[Movies] ([Name], [Director]) values (N'Hello2009', N'Mike') ; insert into [sample].[Movies] ([Name], [Director]) values (N'Star Sky', N'Unknown') ; insert into [sample].[Movies] ([Name], [Director]) values (N'DogAndCat', N'H Miya') ;
日本語を使ってBDDな感じで自然言語DSLも定義できると思います(今回は保存時にShift-JISが選ばれてたようで日本語が通らなかった)。
映画を登録 HOGE 監督 "MO GE"
映画を削除 FooBar
映画を更新 HOGE 監督 MOGE
以下は、雑感です。
モデルエディタについて
「Intellipad」はプラグインをサポートしています。そのためプラグインを書けば、独自DSLに応じた動作を組み込めると思います。GUIモデルデザイナーの「Quadrant」も同じになると思います。
SQL Server
SQL Server以外でOsloが実装されることは無いでしょう。もしかしたら、Osloで必要な機能が次期SQL Serverに追加されることもありえるかもしれないですね。ちなみに.NET Rocksで「We absolutely, we love SQL server」と言ってました。
AndroMDA.NETとの違い
AndroMDA.NETはモデル駆動開発をする点では似ていますが、AndroMDAがNHibernateのコードを生成するのに対して、OsloはSQL Serverのコードを生成します。あと、UMLという汎用言語ではなく、データ指向のM言語を使ってモデリングします。静的な属性だけでなく、具体的な振る舞い(LINQ)もモデルに記述できます。さらに、独自DSLの定義などができます。
Oslo+M言語は、単純なコードジェネレーターではないので、開発の感覚が少し変わるのではないかと思います。
Visual Studio DSL Toolsとの違い
VS2005(2008)SDKに含まれているDSL Toolsも、ドメイン特化という意味では、似たようなコンセプトですが、M言語がIntellipadとQuadrantというモデル専用ソフトを使うのに対し、DSL ToolsはVisual Studioの中でのみ使えるという違いがあります。モデリングするメンバが開発者だけの場合には、DSL Toolsは悪くないと思います(VSだけで作業できるので。まあIntellipadとQuadrantの機能がVSに統合されるかもしれないですが)。
個人的には、DSL ToolsはDSLを定義するツールではなく、VSでモデルドリブン開発をサポートするツールだと思います。DSL Toolsの好例を見たい方はLightSpeedをインストールしてみてください。
M Language(モデル言語)の分割
M言語では、exportといったキーワードが定義されています。このキーワードを使うと外部のモジュールにモデルを公開できます。importキーワードを使うと、その外部モデルを参照できます。M.exeコンパイラでは、M言語のソースがなくても、MXメタデータに参照設定してコンパイルすることもできるので、モデルをユースケース毎に分けたいといった要望にも答えていけるのではないかと思います。
M Grammer(DSL定義)でできること。
M Grammerは、M言語を出力するためだけのDSLではないです。ツリーを呼び出して、C#(VB)で自由に処理を書くことができます。例えば、音符(Song)のサンプルを見ると、動的にMGコンパイラでツリーを生成して、読み出して、任意の処理を記述しています。
この辺の操作をするためのライブラリ(DynamicParserクラス、MGrammarCompilerクラス、GraphBuilderクラス等)も提供されてます。DLRと組み合わせることで、動的にDSLをコンパイルしたり実行したり、色々できそうです。
リポジトリについて(Oslo Repository)
リポジトリはOsloのコアです。リポジトリには、300近いテーブルがあります。M言語で定義したモデルの管理、データの管理、バージョンの管理などをすると思います。CTPに含まれていないので未確認ですが、QuadrantとWFで設定した手続き(フロー)もこのリポジトリに格納できるようです。
M言語から生成されるSQLにはトリガも含まれています。このトリガを使って、リポジトリとの連携や、トラッキング(AOP的)を行うのではないかと思います。ちなみに、このリポジトリ自体もM言語で記述されています。
個人的には、スキーマ変更に伴うデータの移行がどうなるのかが気になるところです(自動になるのか、移行方法をM言語で書くのか、モデルエディタが生成するのか)。このリポジトリの出来次第で、Osloが業務で本当に活用できるかが決まってくると思います。
まとめ
SQLとモデルの抽象化で興味をそそるところが多く、つい時間を使ってしまうので、この辺でやめておきます。まだCTPの段階なので、製品版が出てくるのはまだまだ先でしょうが、今後が気になるところです。
(おまけ)M言語での関連の定義方法
//1対1 module OneToOne { type A { Id : Integer32 = AutoNumber(); } where identity Id; type B { A : A where value in As; } As : A*; Bs : B*; } //1対多 module OneToMany { type A { Id : Integer32 = AutoNumber(); } where identity Id; type B { A : A; } As : A*; Bs : B* where item.A in As; } //多対多 module ManyToMany { type A { Id : Integer32 = AutoNumber(); } where identity Id; type B { Id : Integer32 = AutoNumber(); } where identity Id; As : A*; Bs : B*; type AB { ReferencedA : A; ReferencedB : B; } ABs : AB* where item.ReferencedA in As && item.ReferencedB in Bs; }