オブジェクトグラフ
2007/03/30 (Fri) 22:07:46 JST
EOFはオブジェクトグラフとスナップショット (EOSnapshot) という2種類の仕組みを用いてオブジェクトのコンテキストを管理します。 ただ単純にリレーショナルデータベースをオブジェクトにマッピングするだけでなく、コンテキストの管理によって整合性を保ったりアンドゥ機能を実現することが可能になります(実際にはWebObjectsでアンドゥ機能を使うことはあまりありませんが)。
EOFはオブジェクトの整合性を管理するために、編集コンテキスト上にオブジェクトを集めたグループを用意します。 このグループはCVSのリポジトリに相当し、データベースからフェッチしたオブジェクトや新しく作成したオブジェクトはすべてここで一括して管理されます。 この、オブジェクトのリポジトリがオブジェクトグラフです。
オブジェクトグラフは編集コンテキストごとに異なるため、異なる編集コンテキストでは同じデータでも同じオブジェクトとはみなされません。 また、1つの編集コンテキストで同じデータを何度フェッチしても、そのデータに対応するオブジェクトは必ず1つしか存在しません。
オブジェクトは、IDとセットで管理されます。 このIDはグローバルIDと呼ばれ、メモリ上のオブジェクトを表すオブジェクトIDではありません。 to-oneリレーションシップを持つオブジェクトはグローバルIDと1対1で管理されますが、 to-manyリレーションシップはグローバルID同士で管理されます。
図:オブジェクトグラフ
グローバルID
オブジェクトグラフで使われるグローバルIDは2種類あります。
?TemporaryGlobalIDは、名前の通り一時的に使われるグローバルIDです。 まだデータベースにない、新しいオブジェクトを生成するとこのグローバルIDで管理されます。 オブジェクトがデータベースに保存されるとオブジェクトグラフも更新され、?TemporaryGlobalIDに替わって?KeyGlobalIDでオブジェクトが管理されるようになります。
一方、データベースからフェッチしたオブジェクトを管理するのが?KeyGlobalIDです。 ?KeyGlobalIDは主キー名と値を持ちますが、オブジェクトとは異なりコンテキストの影響を受けません。 同じ主キー名と値を持つ?KeyGlobalIDを比較すると真になります。
オブジェクトグラフでは、同一の編集コンテキスト内のオブジェクトが1つであることを保証するために?KeyGlobalIDを利用しています。 まず、データベースからデータをフェッチする際に、データ行ごとに?KeyGlobalIDを生成します。 次に同一の?KeyGlobalIDが登録されているかどうかオブジェクトグラフをチェックし、もし登録されていればそのデータ行を破棄します。 登録されていなければデータ行をオブジェクトとして生成し、オブジェクトグラフに登録します。
?KeyGlobalIDのサブクラス
ちなみに?EOKeyGlobalIDクラスは抽象クラスです。 実際に使われるのはサブクラスですが、隠蔽されているので具体的にどうなっているのかはわかりません。 keyCount()とkeyValues()が抽象メソッドになっているところを見ると、単一主キーか複合主キーかで別々のクラスが用意されているのではないかと思いますが。
Objective-C版のEOF(WebObjects 4.5)では、keyValues()はパフォーマンスを稼ぐためにC言語の配列を返すようです。 おそらく複合主キーの判別を高速化するためかと思います(EOFは複合主キーの自動生成をサポートしないので)。
Inverse Pages: CoreData基礎:アーキテクチャ CoreData基礎:概要 CoreData基礎 CDPGIntroduction CoreData基礎:オブジェクトグラフ CoreDataデータフォーマット CoreData概要 EOALCommunicateDB EOContextLayers EODelegateFetching EOIFGenerateObjects EOIFQueryDB EOOLWhenUpdateConflict スナップショット オブジェクトのロック オブジェクトストアのロック WebObjects基礎研究室