数据映射器模式只告诉你它应该做什么,而不是它应该如何实现。
因此,本主题中的所有答案都应被视为主观的,因为它们反映了每个作者的个人偏好。
我通常尽量保持映射器的界面尽可能简单:
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()
.
没有真正的方法来实现映射器和域对象交互的“告诉不要问”经验法则。
至于“如何确保您确实需要保存域对象?” ,您可能会想到,这里已经介绍了它,并在注释中提供了大量的代码示例和一些有用的部分。
更新
如果您希望处理对象组,则应该处理不同的结构,而不是简单的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 );
在这种情况下,集合是美化数组,能够接受不同的参数,然后将其用作映射器的条件。当映射器试图存储集合时,它还应该让映射器从这个集合中获取列表更改的域对象。
在这种情况下,映射器应该能够在所有可能的条件下构建(或使用预设的)查询(作为开发人员,您将了解所有这些条件,因此您不需要使其在无限的条件下工作)和为该集合包含的所有未保存的域对象更新或创建新条目。
注意:在某些方面,您可以说映射器与构建器/工厂模式有关。目标不同,但解决问题的方法非常相似。