# mixiに、まったく同じタイトルの日記(中身は全然違う)を書いてみた。こういうひそかな仕掛けをするのが好きw
昨日のことだけれど、VSUG Day 2007 Summerに行ってきた。
午前中のセッションは爆睡してた。ごめん。
で、午後。グレープシティの八巻さんのセッション「Windows フォームアプリケーション開発者は WPF に出会って恋をする」。
…うん、惚れた。結婚してください。
WPFでは、開発者向けのVisualStudioとは別に、デザイナ向けのExpressionというツールが提供されているのは、皆さんご存知の通り。
これによって、デザインとプログラミングが分離されたと言われていたけれど、あそこまで徹底的に分離されているとは思っていなかった。
例えば、ボタン。
Windowsフォームコントロールのボタン(System.Windows.Forms.Button)は、基本的には四角い。オーナードローとかリージョンとか使えば形を変えられるけれど、基本的には四角い。
WPFのボタン(System.Windows.Controls.Button)も、基本的には四角い。でも、これが四角いのは、Windowsフォームのボタンが四角いのとはわけが違う。
WPFのボタンが四角いのは、ボタンがデフォルトでは四角いControlTemplateを持っているから。ControlTemplateを丸いものに差し替えれば丸くできる。
ということは、ボタンの見た目を決めているのはControlTemplateであって、ボタン自体は具体的な形を持っていないということになる。
Windowsフォームの場合は、ボタン自体が四角かった。
ちょっと話が飛ぶ。
オブジェクト指向というのは、何もC#とかJavaとかのことだけを言うんじゃない。
Windows APIだって、立派なオブジェクト指向なのである。
オブジェクト指向の3要素は、「カプセル化」「継承」「多態性」だと言われる。Windows APIの中にも、これを満たしているものは多い。
例えば、Windows APIのウィンドウモデル。CreateWindowExでウィンドウを作り、メッセージを投げて操作するアレ。
アレには、ウィンドウクラスというのがある。はい、クラスが出てきました。実際、ウィンドウクラスはRegisterClassExで1回登録すれば、そこからいくつもウィンドウを作ることができる。クラスとインスタンスの関係そのものだ。
ウィンドウに、標準ではない、ちょっと凝ったことをさせる場合には、ウィンドウプロシージャを差し替えてサブクラス化する。サブクラスってのは、Javaやってる人なら知ってる言葉。C++用語では派生クラス。サブクラス化ってのは、クラスの継承のこと。
オブジェクト指向には複数の流儀があって、C#やJavaの先祖、C++に端を発するものと双璧をなす、Smalltalk流オブジェクト指向というのがある。このSmalltalk流オブジェクト指向で、さっき挙げた3要素なんかよりもずっと大切なのは「メッセージ」という概念だったりする。
トップレベルウィンドウも、その上のコントロールも、すべては「ウィンドウ」でありながら、同じメッセージ――たとえばWM_SETTEXT――を投げると、違う動きをする。トップレベルウィンドウならタイトルバーの文字が変わるし、テキストボックスなら中身の文字が変わる。これは多態性。
そして、ウィンドウの文字列を変える時は、そのメモリを直接書き換えるのではなく、メッセージを投げて行うしかない。これはカプセル化。
このように、Windows APIのウィンドウモデルは、オブジェクト指向の要件を完全に満たしている。
だけど、これには不満があった。抽象クラスというものがないのだ。
すべてのウィンドウは、デフォルトの見た目を持っていて、キーボードやマウスの操作に対するデフォルトの動きを持っている。
Windows APIのウィンドウモデルのクラスには、サブクラス化されることを前提としたものがない。すべてのウィンドウは自己完結できる。その意味で、(抽象クラスの対義語をこう呼ぶならば)すべては具象クラスだった。
.NET Frameworkも、内部ではWindows APIを呼び出してウィンドウを作っているから、これは同じ。C#という言語には抽象クラスがあっても、System.Windows.Forms名前空間のウィンドウモデルには無いと言ってよい。
そういうのがあるから、サブクラス化しても、見た目や動作をカスタマイズすることは難しい部分があった。実のところ、.NET Frameworkでは、Windows APIのウィンドウモデルの上に層が一つ増えることで、ウィンドウプロシージャさえ支配すればどうにでもなるというわけではなくなって、カスタマイズは難しくなった面さえある。
WPFはこれを打ち破った。
WPFのコントロールのひとつひとつはウィンドウではなく、乱暴に言えば、画面上にそれっぽく描かれている絵に過ぎない。だから、見た目はどうにでも変更できる。
セッション資料にあった、小さなクラス図に、俺の目はくぎ付けになった。
CheckBoxとRadioButtonの親クラスとして、ToggleButtonというのがあった。
実のところ、俺はまだWPFを触ったことがないから、ToggleButtonというのがどういうものかは知らない。けれど、このクラス図を見て思った。これは抽象クラスだと。WPFに恋をした瞬間だった。
実際には、ToggleButtonは抽象クラスじゃなかった。ウィンドウ上に配置してみたら、何らかの見た目を持っているのかもしれない。けれど、俺があの時受けた衝撃は色褪せない。
ToggleButtonとは、ONとOFFという2つの状態を持つボタンだ。確かに、チェックボックスもラジオボタンもそうだ。
これは、Windows APIのウィンドウモデルにおけるサブクラス化とは違う。ToggleButtonの見た目や動作を部分的にカスタマイズしてCheckBoxやRadioButtonを作っているわけじゃない。「ONとOFFという2つの状態を持つボタン」という、意味の上でのサブクラスなのだ。
クラス継承とは、本来こういうものであると思っている。
UIが抽象クラスを手に入れた。これが俺がWPFに惚れた理由だ。
ちなみに、今までは食わず嫌いだったのだが、このWPF嫌いはDLRが緩和してくれるかもしれないという希望を持っている。