最近、ビジネスロジックがふんだんに盛り込まれた業務システムというのはあまりありません。
「データの出し入れ」が基本ということは、データの格納庫が必要になってくるわけで、それがデータベースになります。最近ではオブジェクト指向データベースも使われ始めましたが、まだまだリレーショナルデータベースの方がよく使われています。
オブジェクト指向で開発していると、ほとんど必ず問題となるのが、リレーショナルデータベースとオブジェクト指向のインピーダンスミスマッチです。データベースは「データ」を扱い、オブジェクト指向は「振る舞い」を扱います。つまり、「振る舞い」をいかにして「データ」に落とすかというのが、問題となるわけです。
最近では、「DAO(Data Access Object」パターンや「O/Rマッピング」というものを使い、オブジェクト指向とリレーショナルデータベースの差を埋める努力がされています。DAOとO/Rマッピングをまとめつつ、業務アプリケーション開発で思ったことを書いていこうと思います。かなり主観的な意見になります。
- ドメインモデリング
-
簡単に言うと、システム要件から問題領域(医療システムであれば医学、とか)の用語を抜きだすこと。さらには、抜き出した用語の必要性や重要性、独立性などを考慮してオブジェクト間の関連をモデル化すること。
- ビジネスロジック
-
ワークフローやUMLのアクティビティー図で分岐処理を行うこと。
ドメインクラスと永続化機構へのアクセスは分けるべし!
ドメインクラスと永続化機構(データベースやファイルシステム)へのアクセスは層を持って分けるべきです。理由の一つは、「単一責任の原則 (The Single Responsibility Principle: SRP)」に反してしまうからです。また、ドメインクラスに永続化処理の責務を負わせてしまうと、処理が複雑かつアクセス手段に依存した形になってしまうので、保守がしにくくなります。
保守がしにくいとは、テストがしにくいと言い換えてもいいと思います。永続化機構に依存したコードは、テスト環境が用意しにくく、環境に依存してしまうことが多いので、非常にテストがしづらくなります。単体レベルでテストが行えないクラスは、安心して使えません。
業務アプリケーションで永続化機構(特にデータベース)を使わないことはほぼありえないので、データアクセス部分は、一つ層を増やしたほうがベターです。データアクセスパターンには主に「DAO (Data Access Object)パターン」と「O/Rマッピング」という方法がとられます。
前者は、永続化機構とクライアントの間にデータアクセスインターフェースを用意して、データアクセスにはすべてインターフェース経由で行うというものです。後者は、オブジェクト指向分析/設計(OOA/OOD)で導出したドメインクラスと、リレーショナルデータベースのテーブルとをマッピングすると言うものです。
結局
永続化機構(データベース)と、クライアントとは一つ層を設けるほうがよい。クライアントがデータベースに依存してしまうと、単体テストや再利用が出来なくなってしまう。
DAO (Data Access Object) + Value Object
「DAO(Data Access Object)パターン + Value Object」 というのは 『J2EEパターン―明暗を分ける設計の戦略』 で紹介されている、データベースアクセスの一つの方法です。
DAOパターンは永続化機構との間にデータアクセス層を増やすことで、クライアント(永続化機構を使うクラス群のこと)がデータアクセスの方法に依存させなくしたものです。データアクセス方法に依存しないと何が幸せかというと、「テストしやすくなる」の一言に尽きます。データベースが変わったときに変更が吸収できるというのもメリットの一つですが、実際にはデータベースが変わることはほとんどありません。
メリット
- 永続化機構(データベース等)のアクセス手段を、ドメインクラスから隠蔽できる
- 画面ベースでデータモデリングを行った場合に、Value Object の単位がぴったりとハマる
- 永続化層が明確になる
- 層が追加されるので柔軟性が増す
- SQL文のチューニングも可能
- キャッシュ戦略が使える(パフォーマンスの向上)
- Virtual Proxyを使って、遅延ロードが可能(パフォーマンスの向上)
デメリット
- クラスの責務の切り分けが難しい
- うまく共通化しないと重複コードの嵐になりかねない
- ツールを使ってコードを生成しないとめんどくさくてやってられない
結局
DAOは、データアクセス層という永続化機構にアクセスするインターフェースを提供する。データのアクセスはすべてDAO経由で行うことで、データアクセスから独立させることができる。外部に依存する部分は層を設けて独立させるのがよい。
O/Rマッピング
「O/Rマッピング」は、オブジェクト指向で言われる「オブジェクト」とリレーショナルデータベースにおける「リレーション」をマッピングしたものです。いまだに多くのデータベースはリレーショナル型になっています。オブジェクト指向アプローチで開発を行う際に必ずと言ってよいほど、「オブジェクト」と「リレーション」のインピーダンスミスマッチが起こります。この問題を解決するために行われるのが「O/Rマッピング」です。
O/Rマッピングが必要となるのは、オブジェクト指向とリレーショナルデータベースの考え方が違っているというのが大きな理由です。オブジェクト指向は、オブジェクト同士の関連を大切にする考え方です。例えば、領収書と明細という関係を考えた場合
オブジェクト指向では、明細データの集合を取得するときに、親となる「領収書ヘッダー」に問い合わせをして、「明細」を取得します。つまり、クライアントは最初から「明細」に直接問い合わせをする事はありません。 逆にリレーショナルデータベースでは、明細データを取得する場合に、直接「明細」テーブルにアクセスします。データベースは「明細」テーブルのヘッダーIDを元にデータを取ってくるのです。
つまり、明細データが欲しい場合には、「明細」テーブルに対してのみSQL文を発行すればよい。しかし、オブジェクト指向でやっているので「領収書」オブジェクトと「明細」オブジェクトを作らなければならない。そのために「領収書ヘッダー」テーブルと「明細」テーブルを結合しないといけない。という面倒なことになってくるのです。
このように、オブジェクト指向とリレーショナルデータベースとで考え方が違っていることから、オブジェクト指向設計とデータベース設計との差を埋めるために「O/Rマッピング」が使われます。
参考
メリット
- 永続化層の実装をクライアントから隠蔽できる
- データベースのテーブルやカラムが変更になった場合に対応しやすい
- オブジェクト指向アプローチで進められる
- コードの自動生成でめんどくさくない
デメリット
- SQL文のチューニングが難しい
- データベース設計の質に左右される
- 永続化層が分かりにくくなりがち
- 細かい検索処理がしにくい
結局
O/Rマッピングはオブジェクト指向分析/設計で導出されたドメインモデルと、リレーショナルデータベースとの差を埋めるために使われている。そもそもO/Rマッピングを使わなければいけなくなる原因として、オブジェクト指向の考え方とリレーショナルデータベースの考え方が違うのが原因である。
そもそもオブジェクト指向設計ってどうなんだ?
僕が思うに、DAOもO/Rマッピングも使う場面とアーキテクチャによっては恩恵が受けられないのです。DAOパターンは、永続化層を設けてデータアクセスを隠蔽するのが目的です。なぜ隠蔽するのかといわれれば、ドメインクラスの独立性を高めるため。でも、ちょっとまってください。ドメインクラスってなんで必要なんでしょう?
ドメインクラスは、問題領域を表したモデルです。問題領域というのはシステムで解決すべきことであるはずです。この、「システムで解決すべきこと」というのは、そもそもなんなのでしょう?業務アプリケーションであれば、いまだにほとんどが「データの出し入れ」を目的としています。(例えば組み込み系などは、ビジネスロジックで出来ているといえます)
つまり、ドメインクラスをオブジェクト指向で分析/設計する必要はないのです。「データの出し入れ」のみを目的とするシステムであれば、ドメインクラスはオブジェクト指向分析/設計ではなく『データ指向アプローチ(DOA)』で行ったほうがよいのです。あくまで、「データの出し入れ」のみを行うシステム設計の場合ですが。
補足をしておくと、オブジェクト指向分析/設計とオブジェクト指向プログラミングは違います。オブジェクト指向プログラミングはすばらしいものです。データを隠蔽して、インターフェースで処理を行う。このプログラミング手法は今後もなくならないと思います。クラスの考え方をオブジェクト指向ではなくデータ指向で設計して、プログラムの開発はオブジェクト指向プログラミングで行う。現在の業務アプリケーションにはしっくりくるのではないでしょうか。
オブジェクト指向設計が生きてくるアプリケーションというのは、業務アプリケーションではあまりないのかも知れません。「データの出し入れ」よりも「処理や振る舞い」に主眼を置いたアプリケーションというのは、今後などのサービス重視のアプリケーション開発が増えてくることで、多くなってくると思います。
参考
@IT: サービス指向アーキテクチャの未来を考察する(前編)
結局
「データの出し入れ」を行うだけの業務アプリケーションには、オブジェクト指向分析/設計はあわない。『データ指向アプローチ(DOA)』でドメインモデルを設計したほうが、データベースとの相性は良くなる。オブジェクト指向アプローチは、「振る舞い」を重視するサービス指向アプリケーションに向いている。
結局、DAOやO/Rマッピングは使えるのか?
結局、ドメインをオブジェクト指向分析/設計をする必要がなくなれば、「O/Rマッピング」で苦労することがなくなります。「O/Rマッピング」を使わなくなるということではありません。クラスとテーブルが一対一に対応するから、データアクセス層を作って隠蔽すれば、インピーダンスミスマッチが起こらなくなるということです。
結局、「データの出し入れ」を行うだけのアプリケーションであれば、ドメインクラスをデータ指向アプローチで設計し、DAO でデータアクセス層を設けて、O/Rマッピングでテーブルとマッピングするというのがもっともすっきりくる開発スタイルではないかと思います。
結局
ドメインモデルと永続化機構との考えの違いを埋めるためにDAOもO/Rマッピングも考えられている。この差を埋めるのに必死になる前に、一貫したアプローチでシステム開発を行ったほうが効果的なんじゃないのかな。
参考
業務アプリケーションのアーキテクチャパターンで、OOA と DOA の違いについてふれられています。 野村総合研究所 「業務アプリケーションアーキテクチャパターン」
アーキテクチャに関して、どういう点が良くて、どういうところが悪いのかと言う事が、非常にうまく書かれています。
- DAOとO/Rマッピングツールについてのお話を参考にさせてもらいました。
- DAOパターンの意義についてはここを参考にしました。
- オブジェクト指向分析/設計の良書です。