アプリケーションの単位
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的な思考をすると、パッケージ間の依存関係は疎であることが正義なので、商品パッケージから同列にあるカテゴリパッケージを参照するのは抵抗があるわけです。
Teeda(S2Dao)で作った時はこのような依存関係にあるモデル(エンティティ)が存在してしまうため、エンティティはショッピングサイト管理直下(サブではなくメインアプリケーション)に配置しています。逆に各サブアプリケーションでのみ使用する特殊なモデルのみサブアプリケーションで定義する方式をとりました。
Djangoで同じようなことをやってもいいのですが、アプリケーションの下にアプリケーションがある事はあまり推奨されないようです。したがって、coreとかcommonとかというモデル用のアプリケーションを作成することになります。
- /ショッピングサイト管理/core
- /ショッピングサイト管理/カテゴリ
- /ショッピングサイト管理/商品
こんな構成でしょう。
とはいえ、この構成では依存関係は多少解決しましたが、全機能を使う必要がないのにcoreは必ず必須という状況になってしまいますね。アプリケーションの再利用を重視するのであれば、やはり各アプリケーションの下にモデルはそれぞれ定義する方がDjango流なんでしょう。
J2EEとDjangoを比較すると面白いです。J2EEはどちらかといえばクリティカルな業務だったり、設計をガチガチに固めてから実装をする開発スタイルが多い為、先にDB定義やEntity-Daoあたりが固まっているケースが多くなります。逆にDjangoは最初からインクリメンタルな開発が前提ともとれる思想な為、依存関係よりも分割して少しずつリリースし、フィードバックを得ながらアプリケーションを成長させやすいのだと思います。
J2EEとDjangoの選択を迫られたならば、開発スタイル(契約かも?)は選択をする重要な要素になると思います。