アプリケーションの単位

MLでも色々な意見を聞けたので、まとめ。

まず、Djangoの構成を知らない人の為に補足すれば、プロジェクトとアプリケーションという2つの概念があります。プロジェクトにはデータベースの接続設定などの設定項目が記述され、実際に動くコード(modelやview)はアプリケーションという単位で作成します。このアプリケーションは最低でも1つ(もしくはなくとも)Djangoプロジェクトは動きますが、なんらかの機能単位で作成する、という指針となっています。例えば、mysiteというプロジェクトの下に、todoというアプリケーションを作成して、TODOリストのWebアプリを作成する、といった感じとなり、チュートリアルでも紹介されています。

ここで問題となるのが「じゃあ、どんな単位でアプリケーションを分割するべきか?」なのです。

Djangoニッ記は休業中 より

コア開発者の一人、 James Bennetは、PyConでのプレゼンテーションで、「一枚岩指向」に陥らず、複数のアプリケーションに分解して設計するするのが「Django流」だと主張しています。

http://us.pycon.org/common/2008/talkdata/PyCon2008/050/reusable_apps.pdf

* Django で開発するときは、まず実現したい機能を最小限に分解しましょう。
* Django のアプリケーションは「ちょっとした機能」を単位にしましょう。
* サイトを複数のアプリケーションの集まりとして雪だるま式につくりましょう。

結論から言えば、「可能な限り細かな単位でアプリケーションを分割する」がDjango流のようです。理由はこんな感じ。

  • アプリケーションの再利用が(設計次第で)容易になる
  • 欲しい機能から実装して動かすインクリメンタルな開発を推奨
  • テスト単位がアプリケーションになるので、影響範囲などの管理が楽
  • でっかいアプリケーションを作ってしまうとメンテや拡張が大変

ここで言うアプリケーションは、Java的に言えばパッケージになります。例えばショッピングサイト管理アプリケーションで言えば、カテゴリ管理機能と商品管理機能は別のアプリケーションという形がベターとまで、分割しているわけです。

  • /ショッピングサイト管理/カテゴリ追加
  • /ショッピングサイト管理/カテゴリ検索
  • /ショッピングサイト管理/商品追加
  • /ショッピングサイト管理/商品検索

とするよりも、

  • /ショッピングサイト管理/カテゴリ/追加
  • /ショッピングサイト管理/カテゴリ/検索
  • /ショッピングサイト管理/商品/追加
  • /ショッピングサイト管理/商品/検索

とした方が管理もしやすいですし、命名規則もパターン化できるので楽ですから。

ここまでは、全面的に同意する部分なのですが、いくつか引っかかる部分がありました。
Djangoのアプリケーションには、view/model/templeteが一式で含まれます。カテゴリに関しては問題がないですが、商品はカテゴリに属している場合、カテゴリのモデルを商品のモデルから参照することになります。つまり、アプリケーション間に依存関係が発生します。Java的な思考をすると、パッケージ間の依存関係は疎であることが正義なので、商品パッケージから同列にあるカテゴリパッケージを参照するのは抵抗があるわけです。
TeedaS2Dao)で作った時はこのような依存関係にあるモデル(エンティティ)が存在してしまうため、エンティティはショッピングサイト管理直下(サブではなくメインアプリケーション)に配置しています。逆に各サブアプリケーションでのみ使用する特殊なモデルのみサブアプリケーションで定義する方式をとりました。
Djangoで同じようなことをやってもいいのですが、アプリケーションの下にアプリケーションがある事はあまり推奨されないようです。したがって、coreとかcommonとかというモデル用のアプリケーションを作成することになります。

  • /ショッピングサイト管理/core
  • /ショッピングサイト管理/カテゴリ
  • /ショッピングサイト管理/商品

こんな構成でしょう。

とはいえ、この構成では依存関係は多少解決しましたが、全機能を使う必要がないのにcoreは必ず必須という状況になってしまいますね。アプリケーションの再利用を重視するのであれば、やはり各アプリケーションの下にモデルはそれぞれ定義する方がDjango流なんでしょう。

J2EEDjangoを比較すると面白いです。J2EEはどちらかといえばクリティカルな業務だったり、設計をガチガチに固めてから実装をする開発スタイルが多い為、先にDB定義やEntity-Daoあたりが固まっているケースが多くなります。逆にDjangoは最初からインクリメンタルな開発が前提ともとれる思想な為、依存関係よりも分割して少しずつリリースし、フィードバックを得ながらアプリケーションを成長させやすいのだと思います。
J2EEDjangoの選択を迫られたならば、開発スタイル(契約かも?)は選択をする重要な要素になると思います。