Web アプリケーションフレームワークとしての考え方(Djangoを例に) #python_adv

2012 Pythonアドベントカレンダー(Webフレームワーク) - connpass 6日目担当です。軽めにざっくりとした入門的なことをかきます。ほんとうはもっと早めの日程にかけたらよかったんですが、ぼーっとしてたらこうなってしまいました。すみません。
この記事を書こうと思ったきっかけは 「サーバーサイドの知識の無さに全俺が泣いた」レベルの入社当時の人に読ませたら少しはアドバイスになったであろうPythonとDjangoの前提知識メモ - 憧れ駆動開発 の記事にいまでも一日10アクセスとかずっとあってなんだかそれの罪滅ぼしになればいいかなという感じです。Pythonウェブサービスつくろうとして Django にいきついた人にとってこのアドベントカレンダーなどを通じてなんらかの手がかりになれば幸いです。

前回のおさらい

そのVirtualBoxで仮想環境をつくるメモ - 憧れ駆動開発の記事では「VirtualBoxUbuntu Server のサンドボックスを作成する」というのをやりました。「サーバーサイドの知識の無さに全俺が泣いた」レベルの入社当時の人に読ませたら少しはアドバイスになったであろうPythonとDjangoの前提知識メモ - 憧れ駆動開発の記事では「Python に入門して、Django でつまづきそうなところを簡単におさらいする」という導入までやりました。今回のアジェンダは以下です。

そもそも Web フレームワークってなに?

このアドベントカレンダーをみているような人には「なにをいまさら」というような内容ですが、CGI を経由していない自分にとってはむしろそういう説明が必要だと思いました。
CGI は Common Gateway Interface といってウェブサーバー上であるプログラムを動かす仕組みです。たとえば一昔前なら Perl で掲示板アプリをつくって CGI にのせて動かすということがけっこうあったりしました。もちろん Python でも SimpleHTTPServer などの標準モジュールで動かすこともできます。これは、自分のつくったプログラムをウェブサーバーとして動かすという意味では充分なのですが、それをもっと「より簡単に高機能を」「より安全に」「より柔軟に」というのをいろいろつきつめていった結果がライブラリとなりフレームワークになっていったと考えてもいいんじゃないでしょうか。
フレームワークというものそのものは「ある目的のための共通便利キット」という感じでしょうか。大きく言えば会社という組織もある目的(事業)を達成するためにコンポーネント(設備や人)を配置するというパターンみたいなものに考えられるんじゃないでしょうか。
そして Web フレームワークという場合、Web サイトや WebAPI をつくるときに共通化した便利セットみたいなものです。ライブラリというとある言語から特定の共通ロジックをパターン化したセットみたいなものとしてありますが、それの Web サイト版だと思えばいいでしょう。この場合は Web フレームワークで Django, Flask, Pyramid, Tornado など出てきてそれぞれ思想や設計が違いますが、Python で Webフレームワークといったら Django は大きな存在感があるといえるのではないでしょうか(Ruby でいう Ruby on Rails くらいの位置にあるような気はします)。

疎結合にする

プログラミングでは疎結合にするということが重要になってきます。「一つの関数にはひとつの機能を提供する」「ネスト(階層)が深くならないようにする」「if がふえてきたら危険信号、設計を見直す」などなど。ちいさくて簡単な初期のころならある程度ひとつのモジュールにババァンと機能を全部載せても問題は出ないのですが、集団で開発したり、大規模になってきたりするとどんどんバグの危険性が高くなってきます。ユニットテストも当然かかれてないでしょう。ソースの見通しも悪くなり、なにが原因でどう動いているのかがどんどんわからなくなっていくでしょう。個人的には以下の本を読むことをおすすめします。

UNIXという考え方―その設計思想と哲学

UNIXという考え方―その設計思想と哲学


リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

Django プロジェクト/アプリにおける構造化

本題です。いままで経験してきた中で「では、Django においてどういう構造化をしたらいいのか?」というひとつの指針を示します。自分が構造化に関わったわけではなくいろいろ見てきた中で……という話なので、そこは勘弁して下さい。あと、この階層構造でほんとうに動くかというと微妙なのでこれは「こんな感じでわけていくといいとおもうよ〜〜」くらいにとらえてください。
また、プロジェクトテンプレートという意味では Django-Skel というのが参考になります
rdegges/django-skel · GitHub

なんてことをかいたけど

まあ最初のうちは1つのプロジェクトに1つのアプリ、 models.py と views.py とテンプレートだけ用意して愚直に動かせればそれでいいと思います。というか自分はまさにそんなことをしていました。どんなにきたなかろうが学習初期段階においてまず動かすときは、それでいいと思います。ただ、「やっぱなんか汚いなーこれ」「どう考えてもこれメンテしたくないコードだよな……」となってきたときはこうした指標をもとにモジュールを切り分け関数を切り分けてユニットテストをかいていくといいんじゃないででしょうか?