データ マッパーパターンは、何を行うべきかを示すだけで、実装方法は示しません。
したがって、このトピックのすべての回答は、各著者の個人的な好みを反映しているため、主観的なものとして扱う必要があります。
私は通常、マッパーのインターフェースをできるだけシンプルに保つようにしています。
fetch()
、ドメイン オブジェクトまたはコレクション内のデータを取得します。
save()
、ドメイン オブジェクトまたはコレクションを保存 (既存の更新または新規の挿入)
remove()
、ストレージ メディアからドメイン オブジェクトまたはコレクションを削除します
ドメイン オブジェクト自体に条件を保持します。
$user = new User;
$user->setName( 'Jedediah' );
$mapper = new UserMapper;
$mapper->fetch( $user );
if ( $user->getFlags() > 5 )
{
$user->setStatus( User::STATUS_LOCKED );
}
$mapper->save( $user );
このようにして、インターフェイスをきれいに保ちながら、検索に複数の条件を設定できます。
これの欠点は、そのようなメソッドを持つためにドメイン オブジェクトから情報を取得するためのパブリック メソッドfetch()
が必要なことですが、save()
.
マッパーとドメイン オブジェクトの相互作用に関する経験則「Tell Don't Ask」を実装する現実的な方法はありません。
「ドメインオブジェクトを本当に保存する必要があることを確認する方法は?」、あなたに思いつくかもしれませんが、それはここでカバーされており、コメントに豊富なコード例といくつかの便利なビットがあります.
アップデート
オブジェクトのグループを処理する場合は、単純なDomain Objectsではなく、さまざまな構造を処理する必要があります。
$category = new Category;
$category->setTitle( 'privacy' );
$list = new ArticleCollection;
$list->setCondition( $category );
$list->setDateRange( mktime( 0, 0, 0, 12, 9, 2001) );
// it would make sense, if unset second value for range of dates
// would default to NOW() in mapper
$mapper = new ArticleCollectionMapper;
$mapper->fetch( $list );
foreach ( $list as $article )
{
$article->setFlag( Article::STATUS_REMOVED );
}
$mapper->store( $list );
この場合、コレクションは美化された配列であり、さまざまなパラメーターを受け入れることができ、マッパーの条件として使用されます。また、マッパーがコレクションを保存しようとしているときに、マッパーがこのコレクションから変更されたドメイン オブジェクトのリストを取得できるようにする必要があります。
この場合のマッパーは、考えられるすべての条件でクエリを作成 (または事前設定されたものを使用) できる必要があります (開発者はこれらの条件をすべて知っているため、無限の条件セットで動作させる必要はありません)。コレクションに含まれる、保存されていないすべてのドメイン オブジェクトの新しいエントリを更新または作成します。
注:ある面では、マッパーはビルダー/ファクトリー パターンに関連していると言えます。目標は異なりますが、問題を解決するためのアプローチは非常に似ています。