2012年4月7日土曜日

Flexリストコントロールでのデザインパターン(とiOSのUITableViewとの比較)

最近、Flexのリストコントロール(データグリッド)をいじってて分かったことのメモ。

Flexのリストコントロール


Flexのリストコントロールとやらは、以下みたいなのがあります。
左から順番に「リストレイアウト」、「ドロップダウンリスト」、「データグリッド」。


んで、このリスト系コントロールというのが「データ駆動型コントロール」と呼ばれるもので使い方に癖があったりします。もうちょっと言うと、ひとつのコントロールの世界の中でMVCデザインパターンが適用されている。ざっくりとした関係は以下。


Viewコントロールの中に「レンダラー」と呼ばれる描画用オブジェクトが存在し、そこにControllerとしてのFlex君がModelオブジェクトを差し込んで描画する。ポイントとしては、レンダラーオブジェクトはユーザの可視領域分といくつかのバッファ分の数しか存在しない。

「レンダラーA」〜「レンダラーC」で「データ1」〜「データ3」が描画されているとして、例えばデータグリッドを下スクロールすると、それまで「データ1」を描画していた「レンダラーA」が使い回されて「データ4」を描画するようになったりする。ようするに、描画オブジェクトのリサイクルについてFlexが面倒を見てくれる。

それによって、100万のデータを画面で扱う時に見えてない99万9990ほど分のModelオブジェクト用の描画オブジェクトが節約される。

Flexのリストコントロールを独自拡張する時は、上記が分かってないとうまく描画されないことに悩んで、ことあるごとにFlexにとって天敵の全行再描画を実施して画面が重くなってしまう。

気をつけないといけないのは、Modelオブジェクトの中で描画用データも保持しておく必要があること。ユーザ操作で文字を赤くした場合に、その「文字が赤い」情報をModelオブジェクトで保持しておかないとそのデータを再描画した際に、文字色がデフォルト色に戻ってしまったりする。ModelというのはビジネスロジックのModelではなくあくまで描画アーキテクチャ上でのModelということ。

IListItemRendererインタフェースの"set data"メソッドをオーバーライドすることにより
ModelオブジェクトをViewコントロールに独自のロジックで設定することが可能になる。

このアーキテクチャのいま思いつくメリット/デメリットは以下。

メリット:
  • 描画オブジェクトのリサイクルをFlexに任せることができる
デメリット:
  • 設計思想を理解するのに時間がかかる
  • 同じリストコントロール上で複数種類のコントロールの使い分けがしづらい(1行目はラベルで2行目はチェックボックスとか)

Flexのレンダラーについては以下がよくまとまっていて勉強になりました。
itemRendererパート1:inline itemRenderer
itemRendererパート2:external itemRenderer
itemRendererパート3:Communication(データのやりとり)
itemRendererパート4:ステート&トランジション

あと、Adobeのヘルプ。
Flex3開発ガイド/Listコントロール

Adobeのヘルプは、量もAppleのほど多くなくてかつ分かりやすくてよく書かれていると思う。まあ、Appleはフレームワークのソースコードを公開してないからあんだけのドキュメントが要るのかもしれないけど。

iOSのUITableViewとの違い


一方で、iOSのUITableViewはちょっと違う。
UITableViewは以下みたいなiOS版リストコントロール。


こいつへのデータの割当ては以下のようにUITableViewDelegateプロトコルのtableView:cellForRowAtIndexPath:メソッドを実装したりする。


Flexのリストコントロールとの違いは、開発者がコードの中でヘルパーメソッドdequeueReusableCellWithIdentifierやらinitWithStyle:reuseIdentifier:やらを呼び出し自力で描画オブジェクトのリサイクルをすること。

意識する必要のあることはこちらの方が多いが、リサイクルするしないをオブジェクトの識別子文字列(上記の例だと@"MyIdentifier")によって開発者が決められるため、Flexリストコントロールのデメリットであげた「同じリストコントロール上で複数種類のコントロールの使い分け」が比較的しやすい(識別子文字列でそこを意識すれば良い)。

ようするに、少し手間がかかるけどこっちの方が好き勝手しやすそうだ。まあ自由には責任が伴うのが常なので、粗悪な設計の影響を受けやすいけど。

その他Flexについて


Flexは他にもプロパティ無効化(invalidateProperties)や描画無効化(invalidateDisplayList)などの非同期な描画アーキテクチャを採用していて、世の中的にはFlashオワコンな風潮だけどフレームワークの設計は非常におもしろい。iOSと違って、ソースが公開されているのも良いね。

あとは、以下を読んだりして勉強しました。
asでカスタムコンポーネント(1)
asでカスタムコンポーネント(2)
asでカスタムコンポーネント(3)

コアなのは、UIComponentクラスLayoutManagerクラス

0 件のコメント:

コメントを投稿