第3の選択

Android SDK上で使うことを前提として、ビュー(レイアウト)とモデルとの間でオブジェクトを交換する処理を書かなくて済むような、なんらかのデータバインドの仕組みを書くことにした。
データバインド

あまり考えすぎても仕方が無いので、取りあえず方針だけは決めることにした。

1. Windows Forms方式
2. Beansbinding方式

このどちらも使わないことにする。
常時バインド状態は便利だが、現状では処理コストがメリットを上回る可能性が高いと考える。(あくまで現状であって、アンディ・ルービン氏が言うような2GhzのCPUを持つ機器が出てきたり※1、JIT等の高速化技法によりDalvikの実行スピードが格段に速くなった場合は※2、また再考の必要がある)

ではどうする?

  • ModelBinder方式

モデルバインダはASP.NET MVCのコアコンポーネントの一つで、ここ数年来に出てきた比較的新しいMVCアーキテクチャを実装するフレームワークに見られるデータバインドの手法だ。

ASP.NET MVC Preview 5 and Form Posting Scenarios - ScottGu's Blog

方法としてはモデルとなるオブジェクトと、バインドの対象となるビューの双方にコンテキストを持たせて「パラメタ ←→ プロパティ」「パラメタ ←→ フィールド」間でデータバインドを適宜実施するものである。データバインド中にデータの型を利用する側が要求する型に変換したり、パラメタを集約して新たな型を合成したり、不要なパラメタを除外したり等付加機能が用意されている。(EntityFrameworkやLINQとの連携は.NETでは無いので対象外とする)

この方法の一番のメリットは、常時バインドを確立する必要が無く、UIスレッドに影響する程に処理が重くならないと予想されることだ。
ボタンが押されたタイミングでバインドしたり、初期化処理時に一度だけバインドしたりと、必要なタイミングでバインドのタイミングを制御できるため、バインド処理のコストを下げることができる。
もう一つはコールバックメソッドを実行する際にメソッドパラメタにパラメタから生成したモデルや関係する他のクラスのインスタンスなどの依存性を注入できることである。この辺が昔からあるASP.NETのプロパティを同期するデータバインドと全く違う、最も特徴的な部分である。(と私は思っている)

私はASP.NET MVCのモデルバインダが非常に気に入っているため、今回の実装でもこの設計を取り込んでいくことにする。ただし、ASP.NET MVCはサーバサイドWebアプリケーションのフレームワークであり、それをAndroidに適用するには幾つかの仕組みが必要になる。

    • GUI(View)の任意のプロパティをバインドパラメタとしてマップする

サーバサイドのWebアプリケーションであれば、バインドするデータの元はHTTPRequestとしてポストされたパラメタの並びなので、基本的には非常にシンプル(パラメタ名=値の並びしかない)だが、Activity上に配置されたGUIとそのプロパティはアプリケーションによって違うので、それをバインドできるパラメタの並びに変換しなくてはならない。

    • データバインドを実施する方法とその認識

これもサーバサイドのWebアプリケーションであれば、HTML上のボタン押下などによってPOSTされたデータがリクエストとして生成された時点が、データバインドのタイミングだが、通常のGUIではなんらかのイベント(ボタン押下、アイテム選択、フォーカス遷移)がそのタイミングとなるため、イベントを捕捉する方法が必要になる。

    • モデル → ビュー方向のデータバインド

元々、モデルバインダによるデータバインドはビュー → モデルの一方向のバインドが基本であり、ASP.NET MVCの場合データバインドの実施結果をモデル又はステートを介してビューに反映することができたが、GUI相手の場合、モデルの変更は何らかの形でマップしたプロパティに反映する仕組みが必要になる。


以上、ASP.NET MVC程リッチにはできないしするつもりもないが、基本的な機能、特に任意のパラメタ、もしくは任意のPOJOにマップされたビューの値をメソッドパラメタに注入する部分をハイライトとして実装に入る。

※1「「アンドロイドの父」が語るグーグル携帯第2弾 モバイル-最新ニュースIT-PLUS
※2主観だが、現状のDalvikは処理系を考えると十分に速いと思う。Javaだって最初はこんな速くなかった。