[開発プロセス#13] アプリケーション全体を改めて記述する(2)

前回の続きである。前回はユーザーインタフェース要素、つまり、HTMLで記述できる要素は、仮想的に変数とバインドされているという仕組みの考えた上で、ユーザーインタフェース要素と、処理の記述の分離ができていることを説明した。その時の図を利用して、続きを説明しよう。

ここで処理は、分類1から5までに分けて記述をした。このうち、分類3と4がサーバーで他はクライアント側の処理として実装するのが効率良いと考えたとする。「分類2」は、最初に検索フォームを表示する仕組みを記述しているので、特にギミックがないのであればスタティックなHTMLを表示するだけになる。この図では、HTMLの表示には、その要素のHTML記述をテンプレートとして、それを元に画面を構成して表示するという記述で統一することにする。

「分類1」は、フォームに入力された検索条件を元に検索を行い、その結果を画面に表示するまでの、残りの分類を全て通ることになる。分類1については、以前に考えた基準に従って、「やるべき処理」をボックスにして記述をしたが、ここでまず、違和感が出てくる。やはり、ここでは、ボックス間の矢印は「次の処理」を示すことになり、ボックスによって矢印による処理の段取りが変わってくる。であれば、同じ矢印で示すのはどうかと考える。このボックスと矢印の記述の意味を検討して改良することは次のステップで進めることにする。

「入力内容検証」となっているが、設計であるのなら、どのような検証を行うのかを記述すべきであることは明白である。ここでは、OCL等を利用した記述を行うのが順当と考える。

入力に問題がなければ、その値を持ってサーバーからデータを取りに行く。ここで、分類1から分類4にかけては、要するにサーバに対してHTTPのリクエストをPOSTメソッドで行うというごく一般的なCGIの仕組みを利用することになる。「サーバーへPOSTメソッド」から「POST受け入れ」までの処理は、時代によって記述方法が違っていた。古くから行われているのは、FORMタグ要素のSUBMITボタンを利用することで、POSTメソッドをサーバーに投げるということだ。そして、PHPを利用していれば、「POST受け入れ」は自動的に処理されて、分類4は言語要素というか、Apache等のWebサーバーとの連携の中で処理がなされて、POSTメソッドに含まれるパラメータが変数に設定されて、プログラムのファイルの1行目からが実行されるということになっていた。分類5については、PHPを使うのであれば、echoコマンド等で出力した結果をバッファに蓄え、クライアントに送り返す。ここはリクエスト-レスポンスの関係を分離4の部分が担う。その意味では、分類4の部分は、よほどのことがない限り、自分で作ることはないと言えるだろう。分類3がサーバーサイドでの処理の部分である。

なお、FORMタグを使って検索条件を送り込み、その結果を表示するとしたら、分類5の「検索結果表画面生成」はサーバー側の処理となる。それをブラウザはそのまま表示すればいいからだ。しかしここで、分類1〜分類4までの流れをAJAXで実装したとする。そうすれば、おそらく、サーバーから受ける分類5のインプットの部分は、JSONなどの純粋なデータのみになると考えられる。そのデータを、クライアント側が保持する一覧表のテンプレートと合成して、実際にページとして表示される。これは、モダンなJavaScriptプレームワークに共通した仕組みであると言える。

これまでに検討した記述方法で全体像を記述してみたが、前述の通り、ボックスと矢印の部分の違和感を払拭することが必要であると考える。また、バインドしている事実が明白であれば、たとえば、フォームないの「名前」と「名前:検索条件」と記述した変数とのステレオタイプがbindingの関係は明白なので、この関係は1つのオブジェクトで記述しても良いだろう。また、ボックスと矢印がどの変数をアクセスするのかをより詳細に記述することにより、ユーザーインタフェースと処理プロセスの間の同時存在必要性も見えてきて、モジュール分離の指針にもなると考えられる。これらの点を引き続いて考えて行くことにする。

[開発プロセス#12] アプリケーション全体を改めて記述する

開発プロセスの検討を継続的にブログの記事にしてきたが、前の書き込みから3ヶ月が空いてしまった。しかも、#11はフレームワークの機能との分離を目指すことを書いたが、ちょっと順序を間違えたかもしれない。これまでのところで、Webアプリケーションの設計図を描くということを目指しているのだが、ユーザーインタフェース要素と処理の明確な分離がまず1つの目標であった。そして、ユーザーインタフェースは概念的な意味での変数にバインドしているという状況を記述するものであった。その間を、使用しているデータ(あるいはモデル)をある程度意識しながら、「処理の流れ」を記述することを検討していた。

Webアプリケーションとして、検索フォームがあって、その結果を一覧表示するようなものを検討してきたが、ここまでの検討の結果を利用して、図をさらに詳細に描いて見たのが以下の図である。図がだいぶんと大きくなってきた。また、書きながら問題点も出てきているが、まずは、図が何を示しているか、あるいは図が何を表現できているのかをまずは説明しよう。

まず、図の左側には、<<user interface>>というステレオタイプが記述されたサブシステムによる3つの「画面」が縦に並んでいる。「フォーム」と「一覧表」の2つだが、エラーメッセージ用にダイアログボックスが表示されるとすると、ダイアログボックスは「フォーム」の一部であるとも見ることができる。以前に説明したように、「フォーム」では、検索条件を入力するテキストフィールドがあり、「検索条件入力画面」というバウンダリーは、「名前」などのテキストフィールドから構成される。また「検索」ボタンをクリックするとデータベースから検索を行い、その結果を一覧表示に表示されることを期待する。エラーメッセージを表示する「JavaScriptアラート」は、メッセージとOKボタンの処理から構成される。

「一覧表」画面も、同様に「検索結果表示画面」というバウンダリーに代表されるが、名前や住所などのエンティティを表示する。「一覧表」の中の記述だけでは、一覧表になっているということが不明確である点は何らかの検討が必要と考える。

バウンダリーの要素としてはテキストフィールドやチェックボックスなどがあり、図では「検索条件入力画面」のコンポジションの1つである「名前」や「住所」などのように、具体的な定義が記述されている。Web開発ではその要素を参照して…というプログラムを書くか、あるいはフォームの仕組みを利用してサーバーにサブミットすることで終わりとなるが、ここでクライアントサイドの動作の詳細を検討するために、バウンダリーの要素は変数とバインドしていることにする。図では<<binding>>というステレオタイプで記述しており、「名前:検索条件」がその一例である。こうすれば、画面上の要素の設定や取得は、変数に対して行うという処理で一貫性が出てくる。しかしながら、実際にはそこまでの動作をやるとしたら、何らかのフレームワークを使うだろう。ここではフレームワークを取り入れた設計を先々では考慮したいので、あえてバウンダリーの要素を変数にバインドするという記述を行うことにする。

一方、「検索結果表示画面」バウンダリーについてはどうだろうか? 変数とは言え、単一のフィールドなら変数でいいとしても、データベースへのクエリーで得られたものであれば、結果的にはレコードという1つの集まりとなり、それらがさらに配列等で複数存在する結果を記録できなければならない。図では「レコード」、および「レコードセット」と表現している。一覧表にデータを表示するとなると、バウンダリーの要素(図では一覧表サブシステムのコンポジション「名前」など)は、テキストフィールドにしてもいいのだが、通常はTDタグ要素や、あるいはその中のP/DIV/SPANなどのタグに値として設定することになるだろう。テキストフィールドの場合には、変数とのバインディングということは考えやすいが、編集不可能なタグ要素についても、その要素と変数がバインディングしていると考えることが必要と考える。ただし、通常は、変数に値を代入すれば、それが要素に出てくると言った、変数→要素という一方向のものである。しかしながら、ある同一のレコードの、同一のフィールドの値が、テキストフィールドとDIVタグ要素に表示されているとする。単にHTMLだけの実現ではテキストフィールドの値を変えても、DIVタグ要素の値は変わらない。しかしながら、同一の変数、あるいは変数間の同期を実現しているのであれば、テキストフィールドを変更すると同時にDIVタグの表示が変わるということが実現可能となる。結果的に、データベースから取り出した値を有効に使うにはレコードをオブジェクト、レコードセットを配列で扱うことになるが、それらをオブザーバブル(Observerパターンを適用して、変更結果を他のオブジェクトに伝達する仕組みを持つもの)にする必要があるという議論に到達できるのである。一覧の表示に変数という媒介を考える必要はないと言ってしまえばそれまでだが、バインディングを通じてバウンダリーと背後の処理が連携するという仕組みは、MVVMパターンが持つ大きな特徴の1つでもある。その点でのバインディングを基調とした抽象化はフレームワークを単なるテンプレートエンジン以上の価値があるものへと押し上げたこの10年近くのフロントエンドの発展を支える重要な概念となった。

図の説明はまだまだ尽きないので、続きは次回に説明する。