コンポーネント指向

前からぼんやりと考えてはいたのだが、なんとなくこんな感じ?ってイメージがなんとなくできてきたような気がしたのでなんとなく作ってみた、という話。
コンポーネント指向というとオブジェクト指向とかそんな感じの雰囲気に思えるが、実際のところ定義はさらに曖昧で、「何らかの機能を何らかの手法でまとめてコンポーネントと呼んで何らかの接続方法を提供する」みたいなものである。それがコンポーネント指向だと言うのならそうなのだろう。お前の中ではな。的な。
ということで機能をコンポーネントとして作って、それを基本コンポーネントに追加することで機能追加ができるような仕掛けを考えた。

Mix-inとコンポーネント

既存のクラスやオブジェクトに後から機能を追加する方法としては、Rubyならクラスの継承やモジュールのMix-inがある。が、クラスの継承は単一継承だし、Mix-inは好き勝手に機能を追加できるわけでもない。具体的にはインスタンス変数やメソッド名がぶつかったりすると困ったことになるので、モジュール同士はもとよりMix-in先のクラスやそれを継承したクラスまで含めて注意していく必要がある。
んで、俺としてはあんまり気を使わずにいろんな機能をごちゃっと追加してしまえばそれとなくうまい感じに動いてくれるようなのがいいなあー、と妄想していたわけだ。例えばC++の多重継承による機能追加を最初に知ったとき、イメージするのは自由に機能をがちゃがちゃ組み合わせていくような感じだった。実際にはそんなことなくて、いろんな問題に苦しみつつ設計していく感じであり、非常に残念だった。
そんなことができたらいいな。ま、そんな簡単にできるなら誰も苦労はしないのだろうけども。

基本的な仕掛け

とりあえず未実装&未解決問題はあるがソースはこちら。ベースになっているのはWSのシグナルの機構である。
基本コンポーネントの主な機能は3つ。イベントハンドラ設定及びイベント発行の仕組みと、属性を持つ仕組みと、配下に機能コンポーネントを追加する仕組み。このコンポーネントシステムでは基本コンポーネントへの指示はイベントで行い、属性はインスタンス変数ではなく独自のメソッドでハッシュに格納する形で扱う。これらによりユーザが書くメソッドやインスタンス変数との衝突が無くなるので少しは気が楽になるはず。
機能コンポーネントは親の基本コンポーネントに追加された時にイベントハンドラを親に追加することで、親へのイベントに反応できるようになる。機能コンポーネントから親への通知もイベントを親に投げることで行う。
イベントを投げたり受けたりする感じに全体を構築したプログラムでは、イベントの送受信と処理内容を書くのが基本になるわけだが、機能コンポーネントにそれらの処理を書いて一式用意しておけば、たいがいのことはコンポーネントの組み合わせでできるようになる。かもしれない。

サンプル

サンプルのソースはこちら。sdl2rを使ってマウスの位置に白い四角を描画するだけの簡素なものだがソースは長い。こんなものにこんだけのコード書かないとあかんの?って思う人はDXRubyを使っていただけるとよいだろう。こんな動きなら数行で書ける。
コードのほとんどは機能コンポーネントのクラスとSDL2の処理となっている。基本的な使いかたと、sdl2rのタイマのサンプルにもなっている。ドキュメント無いのでな。。。
んで、基本コンポーネントに対して投げたイベントに機能コンポーネントが反応することで、テクスチャを作ったり、マウス移動に反応したり、描画したり、といったことができるようになっている。つまりは基本システム側のコードと、機能コンポーネントが一式揃っていれば、システム的な面でユーザが書くコードはかなり減る、はずだ。コンポーネントの仕掛けはフレームワークを作るときのベースになるもの、とも言える。

おしまい

まあ、何かしら強固なビジョンがあるわけでもないので微妙な話ではあるのだが、これをベースに何か作ってみれば使いやすいかどうか、問題を解決できているのかどうか、残る問題は何か、てな感じのこともわかってくるのではないかと思う。
何を作ってみるのか、というのはあるが。