対決! O/Rマッパー vs. オブジェクト指向DB

第3回 HibernateとCaché、性能比較の結論を出そう

ネクストデザイン
村山 徹
2006/2/3

本事例における設計モデルを比較する

 ここまでで、単純なクラスの永続化、継承と関連を含む永続化について理解できたと思います。次に、本事例の設計モデルを見ていきましょう(この設計モデルは1つの例です。HibernateやCachéを使用する際に、このようなモデルにしなければならないというわけではありません)。

 今回の設計モデルでは、次の点に留意しました。それは、GRASPパターン(参考:『実践UML ―― パターンによるオブジェクト指向開発ガイド』、クレーグ・ラーマン著、依田光江 訳、今野睦、依田智夫 監訳、ピアソン・エデュケーション刊、ISBN4-89471-386-1)の疎結合性と高凝集性を保つことです。つまり、「ドメインクラス」と「永続化の責務を持つクラス」の役割を明確に分けることです。

 その結果、設計モデルは図3のようになっています。右側のCaObjectとそのサブクラスが永続化の責務を持ち、左側のCmObjectとそのサブクラスはドメイン固有の責務を持ちます。そして、左側の「ドメインクラス」は、永続化に関する責務を、右側の「永続化の責務を持つクラス」に委譲します。

図3 GRASPパターンを採用した設計モデル(画面をクリックすると拡大します)

 この設計モデルには次の利点があります。

高凝集性と疎結合性が保たれている

 Cachéを使う場合、「永続化の責務を持つクラス」(図3の右側)に相当する部分はCachéスタジオを使って自動生成します。本稿ではこれまで、Cachéスタジオの中では永続化する属性だけを定義してきました。しかし、実際には、ドメイン固有の振る舞い(ビジネスロジック)を定義することもできます。その場合、Cachéスタジオは、そのビジネスロジックを含むJavaソースファイルを生成します。ただし、リスト8の(5)に示す「caObject.save()」というインターフェイスが示すとおり、そのクラスは永続化の責務も持っています。

Database db =
  CacheDatabase.getDatabase (url, username, password);      (1)
db.transactionStart();                                      (2)
CaObject caObject = new CaObject(db);                       (3)
caObject.setName("レポートを作成する");                        (4)
caObject.save();                                            (5)
db.closeObject(caObject.getOref());                         (6)
db.transactionCommit();                                     (7)
db.close();                                                 (8)
リスト8 CaObjectのインスタンスを永続化するコード(第2回のリスト6を再掲)

 これは、GRASPの情報エキスパートパターン(責務―この場合は永続化―に必要な情報を持っているオブジェクトにその責務を割り当てる)には適合しますが、疎結合性と高凝集性を保つという点では推奨されません。そこで、Cachéが自動生成するクラスには、永続化の責務だけを割り当て、CmObject以下(図3の左側)にドメイン固有の責務を凝集させることで、疎結合性と高凝集性を維持しています。

 Hibernateの場合、POJOが実行時に拡張され、永続化の責務を果たすようになります。第2回のリスト3、および今回のリスト2、3のPOJOにビジネスメソッドを追加すれば、永続化のためのコードを書かなくても、ビジネスロジックと永続化の両方の責務を持つようになります。つまり、このPOJOには永続化のためのコードはありませんので、疎結合性と高凝集性に悪い影響はないようにも考えられます。しかし、アプリケーションコード(第2回のリスト4)にある、接続やトランザクションに関するコードもPOJOに含めることになってしまいますので、やはり、図3のように責務を分担させる方がよいでしょう。

依存性が可換である

 そして、最大の効果は、ドメインクラスをほとんど変更することなく、永続化の責務を持つクラスを交換するだけで、Hibernateを使った永続化方式と、オブジェクト指向データベースを使った永続化方式を実現できることです(図4)。これは、筆者の予測であり、本事例でも検証していませんが、DIコンテナを利用すれば、さらに容易に実現できるのではないかと思われます。

 つまり、設計モデル自体は同じで、永続化のためのクラス

  • 実行時に拡張されるPOJO
  • 自動生成されたクラス

を切り替えるだけで2つのバージョン(HibernateバージョンとCachéバージョン)を実現できるということです(本事例の場合、ドメインクラスにも多少の変更が必要です。ただし、それは機械的で少量の変更です)。

 このように、設計モデル自体は、どちらの永続化方式の場合も、ほぼ同じにできます。これは、もともとインピーダンスミスマッチが生じないオブジェクト指向データベースと、Hibernateが提供する永続化インターフェイスは、基本的に同じであることを示しています。この結果、設計モデルの作成時点で永続化の方式を決めてしまう必要はないといえます。パフォーマンスや費用などの観点から、後で選択することも可能でしょう。

図4 サンプルアプリケーションの2つのバージョン
(トランザクションマネージャやパーシステントマネージャに相当するクラスなどは省略しています)

  3/4

 Index
対決! O/Rマッパー vs. オブジェクト指向DB(3)
HibernateとCaché、性能比較の結論を出そう
  Page 1
・はじめに
・継承と関連の定義(Hibernateの場合)
  Page 2
・継承と関連の定義(Cachéの場合)
・アプリケーションコードを書く
Page 3
・本事例における設計モデルを比較する
  Page 4
・総合的な性能比較
・最後に


対決! O/Rマッパー vs. オブジェクト指向DB


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間