J2EEアプリケーションアーキテクチャ

思いついたことを気ままに書いてみる。

プレゼンテーションレイヤにおけるDTOの使用

プレゼンテーションレイヤにおいて、いつDTOを使うべきか、いつ使うべきでないか。

No DTO!

ドメインモデルに依存しないプレゼンテーションは存在しない。したがって、常にDTOを使い、ドメインレイヤへの依存を避けるのはやりすぎのように思う。依存関係の方向が、プレゼンテーションレイヤからドメインレイヤであれば問題ない。

DTOが必要な場合

プレゼンテーションレイヤが必要とするドメインの知識が複雑すぎる場合、あるいはプレゼンテーションレイヤのモデルとドメインレイヤのモデルに大きなギャップが存在する場合は、DTOを使うべき。プレゼンテーションレイヤにたいして、単純なAPIを提供するのは、サービスレイヤの役目のひとつであり、そこでDTOを使うのはよいアイデアである。

プレゼンテーションレイヤにおけるSQL文の発行

プレゼンテーションレイヤにおけるSQL文の発行に関する問題。

JSPアーキテクチャ上の制限

JSPやタグライブラリの中でSQLエラーが発生しても、適切なエラー処理をおこなうことができない。したがって、プレゼンテーションレイヤではできるだけ、SQL文の発行を避けるべき。

レイヤアーキテクチャ違反

プレゼンテーションレイヤで、直接、SQL文を発行することはレイヤアーキテクチャに違反している(基本3レイヤが前提)。View Helperのようなオブジェクトを介在させる場合は、Service To Workerパターンを使うべきである。アプリケーションの主たる関心がビジネスロジックの実行である場合、Dispatcher Viewを使うべきではない。Dispatcher Viewの構造は単純すぎる。

エンティティオブジェクトのlazy loading機能の問題

Service To Workerパターンを使うとしても、O/Rマッピングフレームワークの提供するLazy Loading機能により問題が発生することがある。プレゼンテーションレイヤでエンティティオブジェクトを参照すると、lazy loading機能により、トランザクションの外で意図しないSQL文が発行される可能性がある。これは悩ましい問題。Open Session in Viewパターンを使ったり、トランザクションを分割することにより、データベースにアクセスすることはできる。しかし、エラー処理の問題は残っている。

リッチなエンティティ、シンなエンティティ

オブジェクト指向で作る場合、ほとんどのケースでデータと振る舞いをひとつのオブジェクトにまとめるべきである。ただし、アーキテクチャ上の制約でそうすべきでない場合や、振る舞いをもたない単なるデータの容器が必要な場合もある。

リッチなエンティティ

エンティティが安定していない場合は、リッチなエンティティでないとつらい。プロセスが安定していない場合は、Strategyのようなデザインパターンを使い、その部分を別のオブジェクトとして抽出するとよい。抽出されたオブジェクトもエンティティもドメインレイヤに配置する。

シンなエンティティ

エンティティの振る舞いを変更すると、データベースのスキーマが変更されるようなアーキテクチャのデータベースを使用している場合(かつ、スキーマ移行のコストが高い)は、シンなエンティティのほうが良い。

ドメインオブジェクト、エンティティオブジェクト

ドメインオブジェクトとエンティティオブジェクトは同じものなのか。ドメインレイヤはエンティティオブジェクトだけで構成されるべきなのか。

ドメインモデルの意味の違い

ドメインモデル(RUP)において扱われるのはエンティティオブジェクト、ドメインモデル(RDD)ではエンティティ+α(分析モデルにおけるJacobson的なコントローラの一部、分析モデルにおいてはエンティティの一部だが永続化されないオブジェクト、その他一般概念など)。

レイヤアーキテクチャ

ドメインモデル(RUP)だけをドメインレイヤに配置すると、サービスレイヤが肥大化し、手続き的なアーキテクチャになりがち。たとえ、Entity beanやO/Rマッピングフレームワークを使っていたとしても、これはTransaction Scriptのバリアントに過ぎない。ドメインモデル(RUP)とドメインモデル(RDD)の違い、ドメインレイヤとサービスレイヤにはどのようなオブジェクトが属し、どのような役割を受け持つのかを理解する必要がある。

サービスレイヤ(アプリケーションレイヤ)には、Jacobson的なコントローラの一部、ユースケースに必要だがドメインレイヤに含まれないワークフローロジックなどが含まれる。また、プレゼンテーションレイヤに単純なAPIを提供するのもサービスレイヤの役目。サービスレイヤは、Session FacadeパターンやApplication Facadeパターンで実現されることが多い。

ドメインレイヤは、Jacobson的なコントローラの一部、エンティティ、その他で構成され、ビジネスロジックを実装する。Entity Bean(古いJ2EEアーキテクチャにおいては)やPOJOで実現されることが多い。

出自

おそらく、ドメインモデル(RUP)はデータモデリングのコミュニティから、ドメインモデル(RDD)はプログラミングのコミュニティから出てきたものではないだろうか(推測)。RUP的なOOAやOODに対するOOPコミュニティの批判は、このあたりが原因か?