2010/04/26

MXML as DSL

更新を止める前から、これだけは書いておこうと思っていたのだけれど、ずっと書き忘れてたこと。
MXMLのDSLとしてのプラットフォームの可能性。
ググっても今のところ"MXML as DSL"というそのものずばりなネタを書いている人は居ないので、先を越される前に書いておこうと思う。

まず結論から。

「MXMLはDSLであり、DSLを開発するプラットフォームとして有効」

従って、ここから言えることは「Flexアプリケーション開発はMXMLによるDSLを軸として開発するべき」 ということだ。
# 実は三段論法ちっくになっていて、間に「DSLによるアプリケーション開発は有効」という命題がある 。
# ここは敢えて無批判に認めるものとする。

まず、MXMLはDSLであるということ。
「そりゃそうでしょ、少なくともFlexの画面を作る(特定ドメイン)ための言語(本来はActionScriptによる構築をするところを、画面構造に沿ったXMLという形にした)なんだし」というのは、まず紛れも無いところ。
でも、実際にはValidatorやら画面表示要素でないものの定義も出来るわけで、必ずしも画面定義のためだけのものではない、ということが言える。

というわけで、翻ってMXMLをDSLとして捉えたときに、MXMLとはどういうものかを考えてみたい。

1.画面定義言語


これは元々のMXMLの目的とするところであるのは間違いない。

ここはおさらいと言うか、いうまでも無いところだけども、MXMLというのは画面の構成をXMLのタグ構造として表現しており、

  • XMLの1つのタグが1つの画面コンポーネントを表現

  • XML属性が画面コンポーネントのプロパティ設定を表現

  • XMLの親子関係がコンポーネントの親子関係を表現

  • モジュールはXMLの名前空間として扱う

  • むろん、良く使われるUI部品は提供済み

  • さらに、ActionScriptでいくらでもコンポーネントを作成可能


というあたりの言語の特徴があり、その上で、

  • FlexBuilderなどでのデザインのサポート

  • デザインしなくてもXMLのコードの補完がかなり効く (個人的には、慣れてしまえばデザインモードよりも生産性高いと思う)



という具合。

2. "オブジェクト構造"定義言語


"オブジェクト構造"というはほとんど造語だけど、一言で捉えたかったので、敢えて言ってみた。

まず、「"オブジェクト構造"定義言語」という語の意味全体としては、「オブジェクト構造」なるもの(なんとなくかっこ悪い言い方だけど、今はこういう言い方をしておこう。今回の文脈における定義は後述)があり、MXMLとはそれを定義するための言語、という意味合い。

「オブジェクト構造」の意味するところは何かというと、オブジェクト群(むろん、適切なプロパティが設定されている)とそれらオブジェクト間の関連(参照)、というもの。
ガベージコレクション技術の文脈で言われる「オブジェクトグラフ」と同じような意味合いだけど、さらにオブジェクトの持つプロパティも含まれている。

実際にオブジェクト指向でプログラミングをするときには、オブジェクトの作成があり、必要なプロパティを設定し、オブジェクト同士の関連を設定して利用する(関連の設定と利用は前後する場合がある)けど、この利用に際して出来上がっているオブジェクト間の関連、というあたりの意味合い。

もっと言えば、SpringとかSeasar2とかが持っているXMLと同じことが出来ると言いたいわけ。
# ただし、dicon(Seasar2のオブジェクト定義用XML)などではオブジェクトのライフサイクルもオブジェクトごとに設定できるけれども、MXMLではオブジェクトのライフサイクルは親となるMXMLに対応するオブジェクトと一緒になる、という違いはある。

これでやっていることは、

  1. オブジェクトのインスタンス化

  2. オブジェクトのプロパティの設定

  3. オブジェクト間の関連づけ(正確には、プロパティとしてオブジェクトの参照を設定することになるので、1と2の帰結としてこれが出来る)



の3つ。

特に非ビジュアルなコンポーネントを考えてみれば、そういう理解は間違っていないところかと。

ついでに言えば、ビジュアルコンポーネントの場合には、MXMLCがActionScriptを生成するときに、子タグのコンポーネントをaddChild()している、ということだけで、
ActionScriptとしてのFlashの構造を何らいじることなく、XMLで画面構造を作り上げることになっている。

(2.5 Dependency Injection)

「MXMLはオブジェクト構造を定義できる」ということが分かったけれども、これはMXML側から見た視点。
その裏側として、逆にMXMLに定義されるオブジェクトのほうから見てみると、これはDIをしてもらってることになると思う。

現に、UIComponentというAbstractなオブジェクトを各コンテナコンポーネントは子として持てるようになっているが、具体的にどのコンポーネントが入るかは親自体は知らない。つまり、依存性は無い。
MXMLでオブジェクト構造が定義されるときに初めて子コンポーネントが設定(注入される)される、と捉えられるわけで、構図としてはまさしくDIと言える。

# 個人的に、Prana FrameworkとかでFlexでもDIって言っているけど、個人的にはそんなコンテナは要らないと思う。
# 上にも書いたけど、MXMLではライフサイクルをオブジェクトの単位で変えられないというのはあるけれど、実際に使うかなぁ?というところ。
# DIでは、親よりも短いライフサイクルを持つように子を設定することは無いし、明示的にそういう状況であれば、実はIFactoryを実装したファクトリをMXMLで作って渡してあげれば実現出来る。

3. データバインディング


もう一つ、MXMLは実際にはActionScriptに変換されることで、ActionScriptで出来ることとMXMLとの違いで考えてみる。

それは、他のオブジェクトやオブジェクトのプロパティを含んだ式をデータバインディング式で参照すると、参照先のオブジェクトのプロパティが変化したときに、
自動的に参照元へ反映されるデータバインディングがMXMLで容易に実現できるということ。

しかもメタデータの記述によってデータバインディングが実現できるように構成されているので、Observerパターンのように変にObserveされるオブジェクトが「汚れる」こともない。
# 汚れる: Observerパターンでやりたい要件を実現するために、本来集中したいこと(画面コンポーネントなんだから、UIだよね)とは違う構造を入れなければならない、というのが汚くなる感じ。


まぁ、大体こんなものかね。

ここまでのまとめ


MXMLで出来ることを捉え直し、整理すると、以下のようになる。

MXMLはXMLベースのDSLであり、Flexアプリケーション内の"オブジェクト構造"を定義することができる

  1. オブジェクト定義の結果として画面定義言語の役割も強く持つ(オブジェクト構造の対象が画面コンポーネントである場合にFlashの構造(子のaddChild()のこと)にも設定される)

  2. DSLのボキャブラリであるところのタグは、ActionScriptによって開発することが出来る

  3. オブジェクト構造の構築はDIに他ならない

  4. 構築されたオブジェクト構造は、データバインディングもされる



DSLの記述環境(FlexBuilder)は、開発効率が高まるように構築されている

  1. 画面定義に関してはWYSIWYGなデザインツールでデザイン可能

  2. 非ビジュアルなコンポーネントに関しても、XMLエディタの補完機能がかなり効いている



というわけで、MXMLのDSLとしての可能性はけっこう高そうだ、という話。

DSLの語彙はどうするのか?


実際にMXMLをDSLとして利用していくにはどうするのか、というところが次に問題だが、
端的にはActionScriptでDSLの語彙となるコンポーネントを作っていくことがそれにあたる。
以前の議論で、新しいFormatterを作ってMXML上に定義してみたが、これは大したことはしていない。
MXMLのDSLにおいて、語彙というものは、ActionScriptのスキルだけで作成できるため、さほど敷居も高くないだろう。

DSLの問題点にどう対処するか?


一方で、WikipediaのDSLに関する記事には、
DSLの問題点も以下の通り記述されている。


・DSL自体を設計/実装/保守するコスト
・正しい適用範囲を探すこと
・ドメイン固有な部分と汎用プログラミング言語の構文とのバランス調整の難しさ
・ハードコードされたソフトウェアに比較して性能的に不利な可能性がある


これらについて検証してみる。

1. DSL自体を設計/実装/保守するコスト


言語は、語彙と文法によって構成される。(まぁ、直感的にも間違っていない言明だと思う)
MXMLの文法はXMLであり、DSLを構成するための最大の障壁と思われる文法設計とそのパーサ系の構築という点に関しては、まったく心配が要らない。
MXMLの語彙については、一定のルールに乗っ取って作成されたActionScriptプログラムであれば、それがすぐに語彙になる。
若干、語彙ごとに変わる文法(構文、MXMLで言えば、属性や子タグとして何を取るか、に相当するだろう)は、語彙の作成と共に設計する必要がある。
いずれにしろ、設計/実装/保守については、その基礎が既にあるため、1からDSLを構築するよりは大幅に小さいと思われる。

2. 正しい適用範囲を探すこと


「正しい」が何を意味するのか良く分からないが、適用範囲という意味であれば、さすがにFlexなので画面に関するものであろう。
得られる警句としては、ActionScriptでの記述との住み分けには若干注意が必要かもしれない、ということか。

3. ドメイン固有な部分と汎用プログラミング言語の構文とのバランス調整の難しさ


構文のうち、ベースとなる文法に関してはXMLであるため、全く問題ない。
語彙ごとに異なる構文、とはつまり、DSLで実現したいことに対応する語彙・構文をどう設計するか、ということだろう。
これもあまり悩まないのではないだろうか。

4. ハードコードされたソフトウェアに比較して性能的に不利な可能性がある


MXMLはコンパイル時にActionScriptが生成されるし、DSLの語彙はActionScriptによって構成し、インタプリタのような動作はしない。
従って、性能面で不利になることはないと思われる。
ただし、Flexは元々からしてデータバインディングを多用する性能劣化する可能性がある(経験則)ため、DSLの導入によってそれらを助長してしまう可能性はある。


結果として、Wikipediaの記事を元にすると、

  • ActionScriptでの記述との住み分けで悩まないようにするべきである

  • ActionScriptで作るコンポーネントが語彙であり、その語彙とそのための構文の設計がポイントである


という2点が、MXMLをDSLとして活用するというアイディアの注意点と言えるだろう。

いずれにせよ、大きな障害とは言えないところだろう。