現在、
八角研究所にて、
未踏ソフトウェア創造事業体験記の連載記事を書いています。要は、
Kodougu の開発記録を書いているわけですが、肝心の Kodougu の技術的な点についてはやや濃すぎて書けないでいるので、まずはこちらのブログで書いてみることにしました。
最初は Kodougu のメタプログラミング的な面について紹介します。
■ メタプログラミングとは?
Kodougu はメタプログラミング的な考え方を使って開発されています。メタプログラミングについては以下の記事が分かりやすいです。
メタプログラミング - Wikipedia より
メタプログラミング (metaprogramming) とはプログラミング技法の一種で、ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと。
メタプログラミングというと、コード生成、マクロ、テンプレートなどが挙げられます。その他、DSL を定義することも含まれます。DSL の身近な例でいえば、Rails(ActiveRecord)の has_many のような仕組みを開発することもメタプログラミングと言えます。
■ Kodougu の基本的な考え方
もともと Kodougu は以下のようなコードを書いたら、モデリングツールを自動生成するツールを作ることを考えていました。
なぜそのようなツールが欲しいと考えたのかというと、モデリングツールと言っても、世の中には UML や DFD や ER 図のように様々なモデリングツールがあります。経験上、モデリングツールの対応するモデリング言語を増やそうとすると、似たようなコードを大量に記述しなくてはならず、大変な手間がかかります。そこで、メタプログラミング的な発想を取り入れて、モデリングツールを記述する DSL を作成して、モデリングツールを自動生成しようとしたのです。
Kodougu のモデリング言語設計機能の一番最初のサンプル(Ruby):
class UMLClass < KodouguMetaElement
# 属性の定義
define_attribute :name, :string
define_attribute :stereotype, :stereotype
define_attribute :attributes, :attribute, :array
define_attribute :operations, :opeartion, :array
# 属性への入力チェック
validate_before :name, :process => do |argv|
# 名前の文字数制限とか。
end
# 表記の記述
def render
# ここに描画処理を記述
end
end
上記のコードでは、UMLClass というクラスに、名前、ステレオタイプ、属性、操作というような属性、属性への入力チェック、表記の記述を定義しています。Kodougu がこのコードを解釈して、UMLClass をモデリングツールで使えるようにするわけです。
■ 補足
UML のようなモデリング言語は、メタモデルというものを定義します。メタモデルとは、クラスとかユースケースとかそういったモデリング言語を構成する言語要素にどのような特徴(表記上の形状、持っている情報など)を持たせるか定義したものです。通常のアプリケーションでは、メタモデルはドメインクラスやモデルクラスに相当します。
モデリングツールを開発する場合、メタモデルの実装に加えてツールにおける必要な実装(お絵かきツール的な機能)を行う必要があります。Kodougu は、メタモデルをソースコードとしては実装せず、DSL から自動生成することで、開発コストを低減しています。また、DSL を記述すれば、誰でもいつでも動的にモデリング言語を追加することができるということでもあります。
■ 実際の Kodougu の実装
とはいえ、今は上記とは異なる実装になっています。基本的な考え方は上記のとおりですが、メタモデルの記述にコードを書かなければならないとなると敷居が高くなってしまうので、できるだけコードを書かないでモデリング言語を定義できるようにしています。(ただし、現在は 100% コードを排除することはできていません。)興味のある方は、
モデリング言語の設計手順のデモを参照してください。
■ こうした実装の問題点
こうした実装には、永続化が難しいという問題があります。モデル情報を DB に保存する場合、UMLClass とか UMLUsecase などのテーブルを作ってそこに入れることを考えると思います。しかし、このようにメタモデルを動的に生成できる場合、テーブルの取り扱いが難しくなります。そこで、要素と表示実体と属性のみという単純なテーブルを準備しています。
以下に概念レベルのテーブルを表現したクラス図があります。
http://www.kodougu.net/p/kodougu/diagram/tool/42
モデル情報を読み込む際は、メタモデルの定義を参照しながら、このテーブルから情報を引き出して結合します。このため時間がかかりますが、Kodougu ではキャッシュを多用して処理時間を短縮しています。
■ 参考
Kodougu は、ウェブ上で行った設定を元に、JavaScript のコードを出力します。
実際に出力されるコード(JavaScript)の例はこちらです。(自動生成されたされたコードは非常に読みにくいです。スンマセン。。。)