2008年12月18日木曜日

ようやくiPhoneアプリのパッケージ構成/クラス設計のコツがわかってきました

  • 良いクラス構造を学ぶためには、複数の偉い人のソースを読むのが一番良い

オブジェクト指向言語に限らず、どのようなプログラムを組むにしても、
クラス分割やモジュールの分割は再利用性・保守性を高める上で重要な点だと思います。
もちろん、iPhoneのアプリ開発だってそうです。

Objective-CでCocoa Touchフレームワークを使い始めておよそ1ヶ月、
ようやくこのフレームワークの作法やクラス分割のコツなどがつかめてきました。
まだまだ間違っているところが多数あるような気がしますが、現段階での自分のクラス分割法を晒してみます。

まずはグループ(Javaで言うパッケージ)の分け方から。
私はこんな感じで分けることにしました。ほとんど偉い人のパクりです。
  • Classes
    • Libraries
      各種ライブラリを配置する
      • JSON
      • ImageStore
      • その他自分が作ったアプリのロジックもここに置く
    • Controllers
      View Controllerの類を配置する
      • UIApplicationDelegate
      • UIViewController
    • Views
      カスタムビューを配置する
      • UITableViewCellのサブクラス
      • UIViewのサブクラス

悩ましいのはカスタムビューのライブラリを利用するときなのですが、
一応、Librariesに追加しようと考えています。

自分の書いたロジックはLogicsのようなグループを作成してLibrariesと明確に分けたほうが良いかもしれませんが、
後々自分の書いたロジックも可能な限り使いまわせるようにしたいので、Librariesに入れるようにしています。



クラスの種類を大別すると以下のような感じに。

●View
ビュー。画面。そのまんまですね。

●Controller
UIApplicationDelegateとUIViewControllerがここに属します。データ受け取って画面を書き換えるのがお仕事です。

●Logic
以前はControllerとDataSourceを直接つないでいたのですが、どうしてもうまくいかないので、ControllerとDataSourceの間に1つ層を設けるようにしました。
こいつのお仕事はDataSourceから非同期に受け取ったデータを貯蓄しておき、Controllerにデータを取得するためのインターフェースを提供することです。
データを貯蓄しておけるので、必要なときだけDataSourceからデータを取ってくることができます。
ん?ここまで書いていて思ったけど、LogicというよりLightWeightパターンやProxyパターンに近い?もっといい名前を付けてあげようかな。

●DataSource (Data Access Object, DAO)
実際にデータを取ってくるクラス。HTTPアクセスやらファイルアクセス、SQLiteへのアクセスなどいろいろ手段はありますけど、
いずれの場合でも必ず非同期でデータを取ってくるというところがキモだと思います。

クラス間の結合方法ですが、ControllerとLogic、LogicとDataSourceの間は、Delegateおよびプロパティを使って結んでいます。
Controller -> Logic, Logic -> DataSourceの呼び出しはプロパティからたどってアクセス。
DataSourceは非同期処理を行うので、DataSourceからの返り値はDelegateをたどってControllerまで伝播される仕組みです。
この仕組みは本当に良くできていると思います。非同期処理なのにとても簡単。

現在の課題としては、出来る限り複数のControllerから同一のLogicに対するアクセスを避けるようにしたいのですが、
そのための具体的な方法が良く思いつきません。
Tab barとか作って大規模なアプリになってくると難しそうですねー・・・
delegateだけではなくてCocoaに標準で備わっている通知機能も使っていく必要があるかもしれないと思ってます。