小規模なシステム開発では…という前置きで言えばイベント・ドリブンに対するリクエスト・リプライ方式でJavaScripというかフロントを開発すると楽なのでは?とふと思っているこの頃です。
以前に「戯言。JavaScript Ninjaとイベント指向プログラミングという解決策 | ごみぶろぐ」という記事を書いたのですが…自分が言いたかったのはリクエスト・リプライ方式で実装した方がJavaScriptのフロント開発はもしや楽なんじゃね?と思った…ということでした。イベント指向プログラミングでも間違っていない気はしますけど説明が不十分ですね。
(この記事も何を言っているのかわからないレベルだという自覚はしていますが、それはさておき)リクエスト・リプライという言葉にたどり着くことができなかったです。。。
リクエスト・リプライ方式とは、指揮者(コラボレータ?コンポーザ?)がイベントを補足して処理をコントロールするということを意味します。
イベント発火したオブジェクトを数珠つなぎ的に動作させていくコレオグラフィ(?)を廃して、指揮者を頂点とする中央集権ピラミッドが各オブジェクトの処理をコントロールさせます。
この利点は指揮者を中心に何がどう動くのかが、オブジェクト/コンポーネント間の関係性を深くなくても指揮者のコードを上から見ていけば、何の処理が動いているか分かること…にあります。
コードが上から下への動作することで、あっちゃこっちゃのオブジェクトの中身を気にする必要がありません。コンポーネント指向もオブジェクト間のメッセージを明確に定義はしますが…逆にそれを不要にします。新しくDOMオブジェクトを生成してもイベントを再設定するという手間もありません。生成したDOMオブジェクトの属性…例えばidなどに指揮者が読み取る識別子をかいておく。イベント発生時に指揮者はその属性情報に応じてDOMオブジェクトに対して動作命令を出す。
オブジェクトごとの動作を定義してドミノ崩しのようコレオグラフィを定義するのではなくコラボレータの指示書を予め定義しておくのです。(しかしながら、コンポーネント指向にせよオブジェクト指向にせよ、イベント駆動方式の開発ライブラリしか見たことがありません)
それもそのはず、普通に考えればDomのEventインターフェイスがある以上、個々のDOMのイベントを検知/発火されて実装するのがオブジェクト指向的だからでしょう…。
リクエスト・リプライ方式だと状態をオブジェクトに持たせ次に実行するメソッドをイベントに応じて実行させるというよりは(そうすることも、できる気がしますが)、イベント・ドリブンの部分については、非オブジェクティブな書き方を想定しています。非オブジェクティブというだけで、リクエスト・リプライ方式は現在あまり使われなさそうです。他に使われない理由としてはリアルタイム性に優れておらず、規模が大きくなると複雑になるからのようです。
しかし、jsのフロントだけで「そこまで大きくならない」という甘えに乗じられるのならば、わりとありなのでは…と思いますね。
本当に複雑なものを定義する時は指揮者が順番を担保したほうがいい気がします。
逆に複雑さにランダム性を認める場合はオブジェクトの方にイベント動作を任せる方が自然だと思います。
勝手にまとめると。
- イベント・ドリブン
- オブジェクト指向/コンポーネント指向
- 分散(コンポーネントが主体)
- プッシュ型(コンポーネントが別のコンポーネントに指示を出す=コレオグラフィ)
- リクエスト・リプライ
- イベント指向/非オブジェクト指向(=手続き的)
- 中央集権(指揮者がコントロール)
- プル型(指揮者がコンポーネントに指示を出す)
Webそのものが中央を持たない分散型のシステムでそれが絶対にいいとは言わないまでもリクエストリプライは古臭く全体主義的な芳ばしい感じはします。
コンポーネントの作り方にも問題があるのかもしれませんが、どのコンポーネントがどの順番でイベント発火するかマルチスレッド的に動くようなイベント・ドリブン方式だと分かりにくいところがあります。例えば、divタグに内包されたbuttonタグがあった場合、divタグ内の領域に対するクリックで発火するイベントとbuttonタグをクリックした時のイベントを同時に検知して動かしたい場合は、一体どうすればいいのでしょうか?(ある条件で逆にdivタグのイベントを発火させない場合は、どうすればいいのか?)buttonタグはともかくdivタグをクリックした時のイベントなんておかしな実装!と言われるかもしれないが、実際にそういうケースがありました。おそらくイベンドリブン形式だと、ある条件化でdivタグのイベント発火が起きたり起きなかったりすることをコンポーネント内のイベント処理か、その前段階で制御することになるのでしょう。その状態はコンポーネントに対してイベントを設定するのでしょうか?これって下手するとかえって難しくなりませんか。どのコンポーネントがどのコンポーネントと対話をしているのか見ないといけません。疎結合性に優れた設計に保守がしにくいという死角はないと胸を張って言えるのなら結構ですけど。
どのコンポーネントにどの状態をもたせるか?その状態はどのタイミングで変わるのか?すべてオブジェクトに状態を持たせてオブジェクト間で状態を交換し合うのではなく1人の指揮者(コラボレータ)が状態を管理したほうが楽なのではないか?考えすぎると頭がパンクしませんか、私のワーキングメモリが足りないだけかもしれません。すみません。
まあしかし、それなら状態はすべて指揮者が持ち、それを指揮者が変更することに徹して制御して順番通りにコンポーネントを動作させるほうが、幸せになれる気がしてしまうのです。必ず指揮者を通して順番に処理させるルールに則ることで、シングルスレッド的に単純に動作させることができるので発火の順番をコントロールすることができます。
…というわけで次回(いつか)は、具体的にコードを書いてみようと思います。具体的にコードにする構想ができてきました。
※そもそもJavaScriptというかDOM上でどうやってコラボレータを動かすか?ですがwindow.eventあたりを補足してtarget.idあたりでエレメントを特定してコントロールします。bodyタグのエレメントに限定してもいいかもしれません。後者のやり方で概ね問題なさそうなことは検証済。
※jsはシングルスレッドなので、シングルスレッド的とかマルチスレッド的と言うのは、ただの比喩表現です。
コメント