レイヤアーキテクチャ(プレゼンテーション/サービス)

J2EEだろうと.NETだろうと、ある程度のソフトウェアを作る時に考えるのがアーキテクチャです。アーキテクチャとは、ソフトウェアに一貫性を持たせるための思想や方針であり、加えてそれを具現化した構造のこと、だと考えています。そして、最近だとレイヤ構造のアーキテクチャが流行ってます。記憶がうろ覚えですがJ2EEだと、プレゼンテーション層、ビジネス・ロジック層、EIS(Enterprise Information System)層とかですかね。名前やどこで切るか、といった話は、それこそソフトウェアの特性や、開発上の前提条件、J2EEか.NETか、Webアプリかリッチクライアントか、などの条件で変わってくるし、プロジェクト毎に考えてコンセンサスがとれていれば良いと思います。

ともあれ、いずれの場合においても、私の場合はまず最初に必ず2つの部分に分けることを最初に考えます。それは、プレゼンテーション部分と、サービス部分です。ここでいうプレゼンテーション部分には、ユーザごとの処理やユーザインタフェースに関わる処理が含まれます。そして、サービス部分には、共通的に扱われるビジネスロジックと呼ばれる業務系の処理や、データの永続化の処理などが含まれます。そのプレゼンテーション部分とサービス部分の間を明示的に分けるアーキテクチャが重要だと考えています。ちなみに、『層』ではなく『部分』とあえて言ってます。プレゼンテーション部分には、J2EEでいうクライアント層とプレゼンテーション層を含んでいますし、サービス部分には、ビジネスロジック層やDAO層などが含まれていると考えますので、部分の中に層があると思って下さい。UMLだと、[部分]◇−[層]。

具体的な配置で考えてみれば、リッチクライアントであれば、そのクライアントアプリがプレゼンテーション部分にあたります。そして、そこから呼び出されるWebサービスが、まさしくサービス部分になるはずです。Webアプリケーションであれば、クライアントはWebブラウザになるので、Servlet/JSPもしくはStrutsなどのWebフレームワークで実現する部分がプレゼンテーション部分にあたります。そこでは、画面遷移や表示のみに特化した処理、ユーザ単位の処理(セッション処理)だけを行い、Strutsで言えば、Actionから呼び出す先をサービス部分にします。ちなみにActionは、POJOにならないし単体で存在できないのでプレゼンテーション部分。Webアプリの場合、あえてWebサービスにする必要はないですが、概念的にはサービスとして扱った方が良いです。つまり、インタフェースの粒度は粗めです。こうして考えると、リッチクライアント+Webサービスで作った場合の方が、その考えはすんなりあてはまりますね。このリッチクライアントで実現した事例としては、ObjectGardenの方で公開しているXPの事例がそうでした。

サービス部分は、クライアントのことは考慮にいれず、本質だけを考えて作れば良く、プレゼンテーション部分は、そこから自分に必要な情報を引っ張り出して自分の好きなようにして表示なりをすれば良くなります。そうすれば、プレゼンテーション部分と、サービス部分をほぼ切り離して開発を進めることができます。人数やスキルセットの状況に応じてチームを分けることも可能です。リッチクライアントの場合は特に、プレゼンテーション部分とサービス部分で言語が違ったりするので、特に有効です。実際に前述の事例の時には効果を発揮しました。

また、本来テストのしづらい画面系の処理なんかで画面の確認をする際に、この分断をしていないと、毎回データベースまでアクセスして確認・テストをすることになったりします。そうなると、動かすことに対する抵抗感が生まれ、気軽に確認ができなくなりバグが残されることになります。プレゼンテーション部分とサービス部分を分けておくことで、プレゼンテーション部分ではサービスのモックオブジェクトを用意すれば、プレゼンテーション部分のみで動きを確認することが出来ます。これで自動化していなくてもテストが億劫になることはなくなります。さらに、早い段階から画面だけですが動くものを見ることができ、認識をあわせることができるのです。HTMLでバリエーションに応じた紙芝居を幾つものパターンを作る位なら、これで動かした方が良いかもしれません。そのためには、色々な仕組みが必要ですが、それは別の話。

サービス部分は、ヒューマンインタフェースがなくなりますので、API的なプログラム上のインタフェースから始めることができます。ですので、コードだけで表現できるというか、モデルだけで表現できるというか、エッセンシャルな状態のプログラミングをすることができるようになります。従来、ドメインモデリングとか、オブジェクト指向分析設計で抽出したクラスたちは、ソフトウェア上に登場させづらかったかもしれませんが、これだとサービス部分はシンプルな世界になるので、オブジェクト指向モデリングしたものを素直に落とし込むことができるようになります。しかし、私のお勧めは、こうしたサービス部分にこそテスト駆動開発(TDD)の出番だと思ってます。よくTDDだとプレゼンテーション部分はどうするんだ?とか、どこから始めるんだ?とか聞かれますが、それはこのサービス部分から始めます。サービス部分は結局のところ、インタフェースを持ったPOJOで作ることになるので、TDDも素直に使うことが出来ます。サービスのインタフェースからテストコードを始めて、あとはリファクタリングしながら、クラスを作っていくのです。

サービス部分、サービスという言葉が沢山出てきましたが、これは、要求分析のあたりから関連する話で、自己流XPでも肝となる部分で、サービス指向開発だと考えています。なので『サービス指向』かつ『テスト駆動』なんですね。「指向」と「駆動」の違いもきちんとあるつもりです。しかし、それはまた別の機会に。