è°åº”该处ç†å¤æ‚查询,数æ®æ˜ å°„器或æœåŠ¡å±‚中的æ¡ä»¶ï¼Ÿ

时间:2012-08-13 21:49:14

标签: php domain-driven-design datamapper

this question在此问题上åšäº†å¾ˆå¥½çš„清ç†æˆ‘的困惑,但我很难找到关于æœåŠ¡å±‚的确切é™åˆ¶åº”该是什么的å¯é æ¥æºã€‚

对于这个例å­ï¼Œå‡è®¾æˆ‘们正在处ç†ä¹¦ç±ï¼Œæˆ‘们希望通过作者获得书ç±ã€‚ BookDataMapperå¯ä»¥æœ‰ä¸€ä¸ªé€šç”¨get()方法,接å—æ¡ä»¶ï¼Œå¦‚书的唯一标识符,作者姓å等。这ç§å®žçŽ°ç›¸å½“简å•ï¼ˆé€»è¾‘上),但是如果我们想è¦æœ‰ä»€ä¹ˆéœ€è¦æ›´å¤æ‚查询的多个æ¡ä»¶ï¼Ÿ

让我们说我们希望获得特定出版商在特定出版商下撰写的所有书ç±ã€‚我们å¯ä»¥æ‰©å±•BookDataMapper->get()方法æ¥è§£æžå¤šä¸ªæ¡ä»¶ï¼Œæˆ–者我们å¯ä»¥ç¼–写一个新方法,例如BookDataMapper->getByAuthorAndPublisher()。

是å¦æœ€å¥½è®©æœåŠ¡å±‚直接调用这些[更具体]的方法,或者在调用多个æ¡ä»¶ä¼ é€’的更通用的BookDataMapper->get()方法之å‰è§£æžæ¡ä»¶ï¼Ÿåœ¨åŽä¸€ç§æƒ…况下,æœåŠ¡å±‚将执行更多逻辑“ç¹é‡çš„工作â€ï¼Œä½¿æ•°æ®æ˜ å°„器相当简å•ã€‚å‰ä¸€ä¸ªé€‰é¡¹ä¼šå°†æœåŠ¡å±‚几乎完全缩å‡ä¸ºä¸­é—´äººï¼Œåœ¨BookDataMapper->getByAuthorAndPublisher()等方法中将æ¡ä»¶é€»è¾‘留给数æ®æ˜ å°„器。

让æœåŠ¡å±‚解æžæ¡ä»¶çš„一个明显问题是æŸäº›åŸŸé€»è¾‘泄æ¼å‡ºæ•°æ®æ˜ å°„器。 (这在链接问题here中进行了解释。但是,如果æœåŠ¡å±‚è¦å¤„ç†æ¡ä»¶ï¼Œåˆ™é€»è¾‘ä¸ä¼šä½¿å…¶è„±ç¦»æ¨¡åž‹å±‚;控制器无论如何都会调用$book_service->getByAuthorAndPublisher()。 / p>

2 个答案:

答案 0 :(得分:24)

  

æ•°æ®æ˜ å°„器模å¼åªå‘Šè¯‰æ‚¨å®ƒåº”该åšä»€ä¹ˆï¼Œè€Œä¸æ˜¯å®ƒåº”该如何实现。
  因此,本主题中的所有答案都应视为主观,因为它们å映了æ¯ä½ä½œè€…的个人å好。

我通常å°è¯•è®©mapperçš„ç•Œé¢å°½å¯èƒ½ç®€å•ï¼š

  • 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 Do not Askâ€ç»éªŒæ³•åˆ™ã€‚

至于“如何确ä¿ä½ çœŸçš„需è¦ä¿å­˜åŸŸå¯¹è±¡ï¼Ÿâ€ï¼Œè¿™å¯èƒ½ä¼šå‘生在你身上,hereå·²ç»æ¶µç›–了大é‡çš„代ç ç¤ºä¾‹å’Œè¯„论中的一些有用的部分。

æ›´æ–°

如果您希望处ç†å¯¹è±¡ç»„,我应该处ç†ä¸åŒçš„结构,而ä¸æ˜¯ç®€å•çš„域对象。

$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 );

在这ç§æƒ…况下,集åˆæ˜¯glorified数组,能够接å—ä¸åŒçš„å‚数,然åŽç”¨ä½œæ˜ å°„器的æ¡ä»¶ã€‚当映射器试图存储集åˆæ—¶ï¼Œå®ƒè¿˜åº”该让映射器从此集åˆä¸­èŽ·å–列表已更改域对象。

在这ç§æƒ…况下,映射器应该能够构建(或使用预设的)查询以åŠæ‰€æœ‰å¯èƒ½çš„æ¡ä»¶ï¼ˆä½œä¸ºå¼€å‘人员,您将了解所有这些æ¡ä»¶ï¼Œå› æ­¤æ‚¨ä¸éœ€è¦ä½¿å…¶é€‚用于无é™æ¡ä»¶ï¼‰å¹¶æ›´æ–°æˆ–创建该集åˆåŒ…å«çš„所有未ä¿å­˜åŸŸå¯¹è±¡çš„æ–°æ¡ç›®ã€‚

注æ„:在æŸäº›æ–¹é¢ï¼Œæ‚¨å¯ä»¥è¯´ï¼Œæ˜ å°„器与构建器/工厂模å¼ç›¸å…³ã€‚目标ä¸åŒï¼Œä½†è§£å†³é—®é¢˜çš„方法éžå¸¸ç›¸ä¼¼ã€‚

答案 1 :(得分:4)

我通常更喜欢这个更具体,比如:

BookDataMapper->getByAuthorAndPublisher($author, $publisher)

那是因为我ä¸éœ€è¦é‡æ–°å‘明SQL。数æ®åº“对此更好,数æ®æ˜ å°„器在这里注æ„,应用程åºçš„其余部分ä¸éœ€è¦çŸ¥é“有关如何以具体方å¼å­˜å‚¨æˆ–查询的内容。

如果您使其更具动æ€æ€§ï¼Œæ‚¨å¾ˆå®¹æ˜“通过界é¢æ供过多功能。ä¸å¥½ã€‚

看看你的申请。你会å‘现ä¸ä¼šæœ‰å¤ªå¤šä¸åŒçš„查询。对于通常大约5-10个例程的数æ®çš„主è¦éƒ¨åˆ†ï¼ˆå¦‚果有的è¯ï¼‰ã€‚它的编写速度远远快于想到一些实际上属于它自己的层的动æ€ç³»ç»Ÿã€‚