Strutsは古代、JSFは近代、現代はRails
最近流行の古代、近代、現代パターンで、Webアプリケーションのアーキテクチャを振り返ってみたいと思います。
古代に生まれたStrutsですが、実は結構完成度が高く、WebにおけるMVCパターンは、Strutsでほぼ完成しています。ViewはJSP(Velocityもあり)とタグライブラリで決まり、ControllerもActionで決まり(StrutsそのものもControllerに分類する場合もあり)でしたが、モデルの実装方法は、決定的なものがありませんでした。
実は、モデルには、アプリケーションモデルとドメインモデルがありますが、この辺の考えも明確なものがありません。アプリケーションモデルという言葉は、あまり聞いたことがない方もいるかもしれませんが、SmalltalkのMVCは、既にそうなっているようです。
モデルをデータのみから成るドメインモデルと,アプリケーション固有の情報から成るアプリケーションモデルに分けることで,ドメインモデルの独立性・再利用性を高めています。
このモデルの考え方をWebに当てはめると、ビジネスの構造・振る舞いはドメインモデルで実装し、プレゼンテーション固有の情報は、アプリケーションモデルで実装するということになるんじゃないかと思います。
Strutsでいえば、ActionFormがアプリケーションモデルに近いですね。アプリケーション層をActionとActionFormで実装するって理解したほうがすっきりしてると思います。
Strutsの父であるCraigは、ActionとActionFormを分離させる形態を、実はよく思っていなかったらしく、JSFの仕様の中で、Managed Beanとして、ActionとActionFormを一体化させます。
Craigと北海道に講演に行ったときに、Craigはこういいました。
おいらが理由を聞いたら
Shale(CraigがやっていたJSFのフレームワーク)は、Strutsの2倍生産性が高いんだよ。
「クラスが半分ですむから生産性が高い」というのは冗談だと思いますが、アプリケーション層のデータと振る舞いは、同じクラスにしたほうが、生産性が高いよというつもりだったのかもしれません。
ActionとActionFormが1つだから、クラスも半分ですむからね。
Tapestry、WebWork、Struts2といったポストStrutsを目指したWebフレームワークは、基本的に、アプリケーション層のデータと振る舞いは、同じクラスで実装(分離したければ分離することもできるけど)します。StrutsがアクションのURLをもとにコントローラが起動されるのに対して、近代のWebフレームワークは、ページ(HTMLやJSP)のURLを中心にしてアプリケーションが組み立てられます。
ページ中心の時代になって言われたことは、ブラウザに見えているURLと実際のURLが1つずつずれてしまう問題です。これは、JSFに関係なくフォーワードで遷移していれば、必ずおきるですが、ページが中心のために、この問題が目立ったのです。
リダイレクトで遷移すればこの問題は起こりませんが、ページ間の情報の受け渡しにセッションを使う必要があり、これはセッションの多用という問題を引き起こしました。
そんな中で、でてきたのがRailsです。Railsは/コントローラ名/メソッド名というわかりやすいURLをアプリケーションに提供しました。「/コントローラ名/メソッド名」形式のURLだとURLのずれ問題があまり気になりません(Strutsで気にならなかったのと同様)。
アプリケーション層は、基本的にコントローラで実装しますが、ドメイン層のオブジェクトを直接Viewに公開します。最近のWebフレームワークは、この形式が多いと思います。
SAStrutsもこの形式ですね。StrutsがRails風に生まれ変わったのがSAStrutsだと思ってもらえると、理解が早いと思います。
ただし、最新のSAStrutsでは、ActionとActionFormは分離することを推奨しています。リクエストパラメータを扱うと責務は、独立したクラス(ActionForm)で処理したほうがいいという理由からです。
単純にリクエストパラメータを格納するだけのクラスなら、プロパティのみのスカスカなクラスになってしまいますが、ActionFormの場合、入力値の検証という重要な処理があるので、これは、意味のある分離だと思っています。
元のStrutsに戻っただけなんだけどね。