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

HEADER DETAIL

平澤 章

Ver 0.1 - 1999/3/11
Ver 0.2 - 1999/8/23

1 目的

ヘッダー−明細形式のオブジェクトの永続処理をシンプルな方式で実現する。

2 別名

3 動機

事務処理系アプリケーションでは、ヘッダー−明細形式で保持される情報がしばしば現れる。
(複数の商品をまとめて販売する場合に、売上と売上明細オブジェクトとして表現する場合など。)

このような情報をリレーショナルデータベース上に永続化する場合、通常はヘッダーと明細それぞれを格納するためのテーブルを用意して実装する。
このとき新規登録については大きな問題がないが、変更には次に挙げるようなさまざまなバリエーションがあり、さらにこれらが組み合わせられる場合もある。
ケース1) ヘッダーオブジェクトの属性だけが変更される場合。
ケース2) いくつかの明細オブジェクトの属性が変更される場合。
ケース3) 新たな明細オブジェクトが追加される場合。
ケース4) 既存の明細オブジェクトが削除される場合。

これを変更内容に即して忠実にSQLを発行しようとすると、次のようになる。
ケース1) ヘッダーレコードに対してUPDATE-SQLを発行する。
ケース2) 変更対象の明細レコードに対してUPDATE-SQLを発行する。
ケース3) 新しい明細レコードをINSERTする。
ケース4) 明細レコードを削除する。明細レコードが1からはじまる行番号で管理されている場合、削除された以降の行番号を繰り上げるため、UPDATE-SQLを発行する。

このように個別の変更内容に応じた永続処理をそのまま実装しようとすると、アプリケーションのロジックは非常に煩わしくなってしまう。
このような事態を改善するために、どのような変更の場合でも、いったんすべての明細レコードを削除し、その後に新しい明細レコードをINSERTする方法がある。
この方法によれば、変更の内容によらず同一のパターンで処理ができるため、アプリケーションロジックを単純にすることができる。

4 適用可能性

HEADER DETAILパターンは、次のような場合に適用できる。

5 構造

Header Detail Class Diagram

6 構成要素

7 協調関係

7.1 新規登録の場合

ヘッダー−明細オブジェクトの登録は、ヘッダーと明細両方の属性情報の妥当性を検証する必要がある場合があるため、一意なタイミングにする必要がある。
したがってClientはヘッダーおよび明細オブジェクトを生成し、必要な情報を設定した後、ヘッダーオブジェクトにだけ登録要求(Storeメソッド)を発行する。明細オブジェクトへの登録要求は、ヘッダーオブジェクトが自動的に発行する。

Header Detail Sequence Diagram #1

7.2 変更の場合

変更の場合も新規登録の場合と同様に、ClientはHeaderDomainおよびDetailDomainオブジェクトを生成し、必要な属性情報を設定する。ただしこの場合Clientは、Restoreメソッドを発行することで、HeaderDomainオブジェクトに対して、更新要求であることを伝える。
この更新要求はHeaderPersisterとDetailPersisterがそれぞれ役割分担することで実現される。

Header Detail Sequence Diagram #2

8 結果

8.1 メリット

  1. Domainオブジェクトの単純化
    Domainオブジェクトに対する変更の内容に関わらず、常に同じロジックで変更処理を実現できるので、HeaderDomain / DetailDomainともロジックが単純になり、見通しが良くなる。
  1. Clientオブジェクトの単純化
    Clientオブジェクトは、ヘッダー/明細型オブジェクトを新規登録する場合も、修正する場合も、ほとんど同じロジックでよい(StoreかRestoreかの違いのみ)ため、非常に単純になる。

8.2 デメリット、留意点

  1. 永続記憶へのアクセス処理のパフォーマンス
    この方式では変更時の永続記憶へのアクセス処理は、どのような場合でも、基本的に同じパターンになる。明細の数に変更がなく、1ヶ所の属性変更の場合でも、いったん全明細を削除した後に全明細を登録するため、このようなトランザクションの比率が高い場合、変更パターンに応じてきめ細かな永続処理アクセスをする方式に比べて実行効率が低下する。

9 実装

省略

10 サンプルコード

省略

11 使用例

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

12 関連するパターン

13 参考文献