[デザインパターン/永続化]

QUERY ITERATOR

平澤 章、志村 亮一
Ver 0.1 - 1999/3/11
Ver 0.2 - 2000/1/29

1 目的

永続記憶から特定の条件に合致する複数のオブジェクトを取り出す際に、内部構造を意識させない抽象的なインタフェースを提供する。

2 別名

3 動機

永続記憶に格納されたオブジェクトに対して、何らかの条件に合致するオブジェクトだけを取り出すケースは多い。このようなクエリー処理では、対象となるオブジェクトの件数が多い場合、非常に多くのオブジェクトが一度に生成される必要がある。これをそのまま実装してしまうと、レスポンスタイムの悪化や、メモリリソースの急激な圧迫といった問題が起きてしまう。

また検索の結果を保持するオブジェクトは、一般的にミドルウェアやDBMSを提供するベンダーから用意されるため、製品毎に異なるインタフェースを持っている。ミドルウェアやDBMSを入れ替えてもアプリケーション全体に影響が出ないようにするためには、このような特定の製品に依存しないインタフェースにしておく必要がある。

4 適用可能性

次のような場合にQUERY ITERATORパターンが適用できる。

5 構造

6 構成要素

7 協調関係

Query Iterator Sequence Diagram #1

8 結果

クライアントに対しては、ドメインオブジェクトがリレーショナルデータベースから復元されることは全く透過となる。

ドメインオブジェクトは、クライアントからのIteratorに対するNext()/Get()オペレーションの実行に合わせて逐次復元されるため、検索対象とするドメインオブジェクトが多数の場合でも、メモリリソースを一気に圧迫することがない。

9 実装

  1. JOINによる複数Domainオブジェクトの一括ロード
    クエリーによる条件検索は、取引一覧の表示や、帳票出力などのために使われることが多い。このような場合、1種類のDomainオブジェクトを読み込むのでは不十分で、複数種類のDomainオブジェクトの情報をまとめて表示・印刷する必要があることがしばしばある。
    (例:取引一覧に顧客名や所在地を合わせて表示するケースなど。)

    しかしその場合に、個々のDomainオブジェクトごとに別々のクエリーを発行して、メモリに展開されているオブジェクト上でマージしようとすると、レスポンスタイムやメモリ負荷など、実行効率に大きな負荷がかかってしまう。
    これを回避するために、Persisterオブジェクトで、複数のテーブルに対するクエリーをまとめて発行する方法が考えられる。
    これにより1つのPersisterオブジェクトが1つのテーブルの永続処理に責任を持つという原則が崩れるが、それ自体は実行効率とのトレードオフであり、その場合でも、Domainオブジェクトはこのような永続処理(=この場合は、JOINを使ったSQLで復元されたこと)からは独立させておくことで、アプリケーション全体がDB構造に強く依存する状況を回避することができる。
    Query Iterator Class Diagram #2

10 サンプルコード

省略

11 使用例

某社会計システム

某社在庫&販売管理システム

12 関連するパターン

13 参考文献