フロントエンドの特定技術について語る解説は多くあれど、そもそもフロントエンドのつくりかたについて語った解説は多くないのではないでしょうか。
フロントエンドという大きな領域ですので恐れ多くもありますが、私が GUI プログラミングに携わった経験をもとにお話した内容のスライドとその補足をここでしたいと考えます。
スライド
スライドのページ数は多いですが、差分がほとんどですので、それほど構える必要はないです(カーソルキーに負担がかかるという問題を除いて)。
補足解説
大きなテーマごとに補足をしていきます。
スライドで取り上げているテーマは次の4つです。
- GUI アーキテクチャパターン
- データの同期
- エラーハンドリング
- コンポーネント構造
「GUI アーキテクチャパターン」はいわゆる MVC や MVP といわれるものがどういったものかを解説する章です。
「データの同期」は画面と実際のデータが離れた個所にあるときのデータ同期の話です。
「エラーハンドリング」はどのようにエラーをハンドリングすると手間がかからないのか、ということを主題にした解説です。
最後の「コンポーネント構造」はコンポーネント指向と呼ばれる小さなコンポーネントでくみ上げる画面の構造についての解説です。
GUI アーキテクチャパターン
一般的に MVC パターンというと MVC フレームワークの印象が強く、Web のためのアーキテクチャパターンと捉えられてしまうケースが多いように感じます。
実をいうと MVC とそれに連なるものは Web に限らない、もっと広い範囲を対象にした、つまり GUI のためのアーキテクチャパターンと考えています。
古くはドキュメントビューなどのパターンもありますが、本スライドで紹介しているのは MV からはじまるパターンに限定しています。
MVC
原点となるのは MVC です。
これはユーザの入力をコントローラが受け取り、入力値によってモデルとされているビジネスロジックを実行させます。
結果としてモデルに変化が起き、その変化をビューが受け取ります。ビューはオブザーバーとしてモデルの変化を監視しています。
スライド中のイメージとしてはゲーム機を例にしてみました。
ユーザはコントローラを操作して、それがゲーム機に伝わり、ビューであるモニターに描画される。ユーザはビューを確認してまた操作をします。
コントローラが何をやっているかというと、ボタンを押した事実を伝えるのではなく、それを電気信号に変換してゲーム機に送信しています。
ゲームを遊ぶ際にユーザはコントローラ以外を操作しないということも覚えておいてください。
なお、いわゆる MVC フレームワークはこれとは異なります。
MVC フレームワークではコントローラがビューを描画します。
このため、原初の MVC を古典的 MVC、MVC フレームワークのような形を MVC2 と呼ぶことがあるようです。
MVP
MVC は発展して MVP になりました。
なぜ発展したのかというと、MVC にはひとつ問題があったからです。それはつまり、コントローラがビューと独立している点です。
昨今のソフトウェアを考えてみると、ボタンなどのコントローラに相当するものはビューに組み込まれています。
つまりユーザが操作するのはビューであるのです。
そこで MVC の縛りを少し緩くして、ユーザがビューを操作できるようにしたのが MVP です。
MVP は Humble View と Supervising Controller の2つに分けられます。
Humble View の Humble はつつましいという意味です。
ビューがつつましいという意味で、ビューはモデルの監視をしません。
ビューのデータを更新する役目を担うのはプレゼンターと呼ばれるものです。
Supervising Controller はその逆にビューがモデルを監視します。
MVC と同じような形ですね。
MVVM
MVVM はビューモデルというものがモデルの射影として機能し、ビューとモデルを仲介します。
もっとも分かりやすい違いはビューとビューモデルが双方向バインディングによって結びつくというところです。
それ以外はほとんど MVP と同じ構成になっています。
MVW
MVW は Model View Whatever です。
重要なことはモデルとビューでそれ以外はなんでもいい、という考えですね。
MVC, MVP, MVVM で重要なところは常に変わらない MV の部分であるということを強調したものです。
ここまで紹介したパターンはモデルとビューとユーザがどのように結びつくかを示しているにすぎず、重要なのは C でも P でも VM でもないということですね。
実は私もこのことを数年前から言及しており、MVX としていました。
Model View Xxx、読み方はモデルビューエトセトラです。まったく流行らなかったので忘れてよいです。
Flux
少し話はズレますが、Flux もこれらにかなり近い考えです。
より具体的に言えば原初の MVC や MVP に近く、それらの具体的な実装について言及したものと捉えています。
データの同期
データの同期は軽視されやすいテーマです。
本スライドが主張するのは、クライアントの情報を信用しないようにするということです。
クライアントでごちゃごちゃと変数の中身を入れ替えたりするよりは、MVC のように直接ビューを操作せず、データ元のデータを反映させることで更新するようにすることこそがコードをシンプルにする近道でしょう。
エラーハンドリング
エラーが起きた時にいかにユーザに対して親切であるか、というのはソフトウェアの価値を決定づける重要な要素です。
しかし、すべてのエラーハンドリングが必ずしも必要ではないという事実もあります。
入力項目がひとつしかないときに、エラーをツールチップで表示するのと画面上部に表示するのはユーザにとって大差ありません。
反対にいくつもの入力項目があるときはツールチップで表示してあげるほうが親切でしょう。、
本スライドで解説しているのは、そういった要求にこたえて、前者はなにもしなくてもよく、後者は任意に実装できるようにすべき、という内容です。
コンポーネント構造
コンポーネントが織りなす構造はオブジェクト指向プログラミングのそれと同じです。
すなわち下位コンポーネントに対しての操作はメソッドで行い、上位コンポーネントに対する通知はイベントで行うということです。
最初に考慮すべきはその形にできないかということです。
コンポーネント同士が Flux や EventBus などを利用してグローバルに会話を始めてしまうことは避けねばなりません。
コンポーネントには可能な限り階層関係を構築し、上位から下位はメソッド(バインディング)で、下位から上位へはイベントで、コンポーネント同士の通信をすべきでしょう。
まとめ
GUI に限らず、コードに限らず、すべてにおいて理解の柱となるのはベクトルです。
一定のやり方で、一定のデータフローで、というようにそこにある方向を意識することがシンプルさのためにもっとも重要なことです。
GUI プログラミングで目指すべきことは「テストをする必要もないコード」を目指すことです。
もちろんこれはテストが不要であることを意味しません。
「テストが絶対欲しいと思うようなコード」と「テストがなくてもいいかなと思えるコード」では後者の方がシンプルであることは間違いないでしょう。
※追記
突っ込まれてたしかにベクトルよりアローの方が正しい、と思いました