ディスカッション開始~最初からレイヤーの話へ
参加者:普段Javaを触っていますが、Webアプリケーションで5層パターンを利用しています。HTML層、アクション層、サービス層、ロジック層(業務ロジック)、DAL層、で組んでいるんですが、Web Form / ASP.NET MVC ではどのようなアーキテクチャになっているでしょうか?
――現場の話として、アーキテクチャの話などでJava周りのディスカッションが進みました。
参加者:自分が継続的に開発を進める ASP.NET ASP.NET MVCアプリケーションを作る場合、以下のようにします。
プロジェクトの新規作成時にできる Models ディレクトリはいきなり削除してしまい、「ソリューション名.Models」でクラスライブラリプロジェクトを起こし、本体のASP.NET MVCアプリケーションから参照させます。
これにより、各プロジェクトは名前空間的な参照関係は通りますし、Models側でpublicインターフェースとして公開したものがサービス層のレイヤインターフェースを構成することになります。
参加者:さらにModelsが別DLLとして作ったDALを参照する形になれば、DALレイヤーとビジネスロジックレイヤーを明確に区分することもできるでしょう。
これらのDLLを直接参照するかRemotingなどを介して接続するかについては個々のアプリケーションで考える配置戦略ですが、レイヤリングの方針に基づいてプロジェクトを構成することは容易だと思います。
参加者:結局は責任分担で、レイヤーを切るのが重要だと思います。
竹原:5層はASP.NET MVCでもできます。今回作成したサンプルではModelsフォルダ内のLinq to SQLがDAL層になり、リポジトリがロジック層となります。トランザクションで囲みたいサービス層は独自に作成したServicesフォルダ内に切りだしていて、さらにアクションとしてのコントローラーがあり、HTMLを担当しているビューがいます。5層にしておくとASP.NET MVCでも開発しやすくなるかと思います。もちろん規模にもよりますが。
小野:デフォルトの構成ではServicesフォルダはありません。ASP.NET MVCが用意しているのはModels/Views/Controllersです。@ITで公開されているScott Guthrieの翻訳記事にはリポジトリは自分で考えて書きましょう! と書かれていて、サービスなどはそこに被せてあげると良いでしょう。というのが開発チームの考えのようです。
竹原:リポジトリはDALをシンプルに使用するロジックとしておくことで、サービス層がアプリケーションの機能を提供しトランザクションを一元管理できるようになります。そうすることで、層ごとにテストを分離することができるようになり、それぞれのテストがよりシンプルな機能に対するテストになり、開発しやすくなると思います。
また、サービス層がトランザクション管理することで、「リポジトリを複数利用するサービス層の実装も容易になります。
このように層をはっきりと分けてあげることで先程も述べたように、大規模アプリケーションの開発にも対応しやすくなると思います。
小野:この5層アプリケーションの場合、どこでテストを行いますか?
竹原:まず、リポジトリに書いたロジックが意図したとおりの動きをするのかをデータベースの接続するDataContextでテストします。その後、DataContextを利用しないリポジトリ(モックリポジトリ)を使って、サービス層のテストを行います。その際に、データ更新に関する部分だけはモックリポジトリで内部管理してるList<T>などに直接Addするようにしておくと、更新系の処理のテストも簡単にできます。サービス層のテストができるようになれば、後はそのサービスをインジェクションしたコントローラのテストを行い、意図したとおりのActionResultになるかテストします。その際にModelデータの検証テストも行います。最後に必要であればViewが出力するHTMLが正しいかどうか、Ajax的な動きが意図したとおりになるのかをテストすることになりますが、それはまた別(Seleniumなど)のテストフレームワークを利用して実施することになると思います。
竹原:3つのレイヤーにテストを集中させることで、アプリケーションの品質を高く保てるかと思います。
小野:Web Formで層をわけるとしたら、サービス層、ロジック層、DAL層の部分をなんらかの形で作成しておいて、HTML(ビュー)とアクションを一体化する形でWeb Formのプロジェクトとして作って繋げる、という形になると思います。それ以上に層の分化はしづらいですね。
層をわけてのテストの話になっていますが、Web Formで、例えばDynamic Dataなどのようにコードをほとんど書かないアプリケーションの場合にテストが必要か、と言われるとみなさんどう思います? テストが本当に必要なのか、というところは考えるポイントになると思います。
間違いなく言えることは、5層にしてテストを行いたい! というアプリケーションの場合にはWeb Formはお勧めできません(笑)。
ナオキ:Web FormとASP.NET MVCの決定的に違う点はそこですね。Web Formでもテストはできますが、テストを重視するTDD(Test Driven Development)であるならば、ASP.NET MVCでの開発がお勧めできます。