イベントハンドラが肥大化しつつあるのでStateパターン適用について考えてみた
左上にボタンを配置してそれをタッチすることで、左側にメニュー一覧が表示され、同時にメインのTableViewがスライドするUIを最近よく見かけると思います
※例えばこのような感じのUI
現在の自分のやり方としては、上記のUIの実装をするのにTi.App.Propertiesを活用しています。
CoffeeScriptでのソースになりますが、該当箇所を抜粋しておきます
listBtn = Ti.UI.createButton systemButton: Titanium.UI.iPhone.SystemButton.BOOKMARKS listBtn.addEventListener('click',(e)-> if Ti.App.Properties.getBool("stateMainTableSlide") is false mainTable.animate({ duration:200, left:80 },()-> Ti.App.Properties.setBool("stateMainTableSlide",true)) else mainTable.animate({ duration:200 left:0 }, ()-> Ti.App.Properties.setBool("stateMainTableSlide",false)) )
これで、左側にメニュー一覧が表示しつつ、同時にメインのTableViewがスライドするUIは実現出来てますが、もっと複雑な状態を管理しようとすると、ソースコードが複雑になってくるかなと思ってます。(実際自分が作ってるアプリもその状況に陥りつつあります・・)
複雑な GUI を持つアプリケーションの設計について(Web アプリ編)という2007年の記事から少し長いですが引用します
GUI のいやらしさをよく表現しています。しかし、残念ながら、C# + Windows.Forms を使おうが、Java + Swing を使おうが、Delphi + VCL を使おうが、そのスパゲティから逃れることはできません。
なぜ、C# や Java でもこの問題から逃れることができないのか、考えて見ましょう。確かに、Form や Window を継承したクラスにイベントハンドラを追加していくスタイルは、一見すると、わかりやすくて簡単です。でも、何の指針もなく開発を進めていくと、イベントハンドラに、UI の状態管理、アプリの処理、UI の見た目管理などの処理が混ざることになり、結局、Form や Window を継承したクラスはスパゲティになります。
上記の記事では、スパゲティー化をさけるための考察があり、その中で
UI の状態遷移図を書いて整理して、状態遷移を実現するフレームワークを書いて抽象化してもいいでしょう。State パターンですかね。
という一文がありました。
以前マリオでStateパターン! 〜JavaScript編〜というエントリを自分でも書いたのですが、これをベースにして、CoffeeScript+Titaniumで 実装しなおしてみました
実際にStateパターン適用してみたものを実装してみたことで、どの状態のときに、Viewを構成するどの部品がどのイベントを受け付けるか、自分自身が理解しやすくなりました。
この辺りの部分のテストもCoffeeScript+Jasmineで書けるようになりたいのですが、まだまだ勉強不足なのでノウハウ溜まったらいつかブログに書こうと思います。
P.S. 本当はTitanium mobile "early" Advent Calendar 2012のエントリのネタとして、マリオでStateパターン Titanium Mobile編 のサンプルとして上記のGitHubのやつを 考えていたのですが、どう考えても小ネタじゃなくってネタにしかならないからこういう形のエントリにしてみました