谁应该处理复杂查询,数据映射器或服务层中的条件? [英] Who should handle the conditions in complex queries, the data mapper or the service layer?

查看:70
本文介绍了谁应该处理复杂查询,数据映射器或服务层中的条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题在清除方面做得很好我对此事有点困惑,但是我很难找到可靠的资源来确定服务层的确切限制.

this question did a very good job of clearing my confusion a bit on the matter, but I'm having a hard time finding reliable sources on what the exact limitations of the service layer should be.

在此示例中,假设我们正在处理书籍,并且我们希望按作者获取书籍. BookDataMapper可以具有通用的get()方法,该方法接受书的唯一标识符,作者姓名等条件.此实现是相当琐碎的(从逻辑上来说),但是如果我们要具有多个条件则需要怎么办?更复杂的查询?

For this example, assume we're dealing with books, and we want to get books by author. The BookDataMapper could have a generic get() method that accepts condition(s) such as the book's unique identifier, author name, etc. This implementation is fairly trivial (logically), but what if we want to have multiple conditions that require a more complex query?

让我们说,我们希望让特定作者在特定出版商的指导下撰写所有书籍.我们可以扩展BookDataMapper->get()方法来解析多个条件,或者可以编写一个新的方法,例如BookDataMapper->getByAuthorAndPublisher().

Lets say we want to get all book written by a certain author under a specific publisher. We could expand the BookDataMapper->get() method to parse out multiple conditions, or we could write a new method such as BookDataMapper->getByAuthorAndPublisher().

是让服务层直接调用这些[更特定的]方法还是在通过多个条件调用更通用的BookDataMapper->get()方法之前对条件进行解析是更可取的?在后一种情况下,服务层将执行更多的逻辑繁重工作",从而使数据映射器相当简单.前一种选择会将服务层几乎全部缩减为一个中间人,而在BookDataMapper->getByAuthorAndPublisher()之类的方法中将条件逻辑留给数据映射器.

Is it preferable to have the service layer call these [more specific] methods directly, or have the conditions parsed before calling the more generic BookDataMapper->get() method with multiple conditions passed? In the latter scenario, the service layer would do more of the logical "heavy lifting," leaving the data mapper fairly simple. The former option would reduce the service layer almost entirely to just a middle-man, leaving conditional logic to the data mapper in methods like BookDataMapper->getByAuthorAndPublisher().

让服务层解析条件的明显问题是某些域逻辑从数据映射器中泄漏出来. (在链接的问题此处中对此进行了说明.但是,如果服务层要处理这些条件,则逻辑不会使它超出模型层;无论如何,控制器都将调用$book_service->getByAuthorAndPublisher().

The obvious concern with letting the service layer parse the conditions is that some of the domain logic leaks out of the data mapper. (this is explained in the linked question here. However if the service layer was to handle the conditions, the logic wouldn't make it out of the model layer; The controller would call $book_service->getByAuthorAndPublisher() regardless.

推荐答案

数据映射器模式仅告诉您应该执行的操作,而不告诉您如何实现.
因此,本主题中的所有答案都应视为主观的,因为它们反映了每个作者的个人喜好.

The data mapper pattern only tells you, what it is supposed to do, not how it should be implemented.
Therefore all the answers in this topic should be treated as subjective, because they reflect each authors personal preferences.

通常尝试使映射器的界面尽可能简单:

I usually try to keep mapper's interface as simple as possible:

  • fetch(),检索域对象或集合中的数据,
  • save(),保存(更新现有内容或插入新内容)域对象或集合
  • remove(),从存储介质中删除域对象或集合
  • fetch(), retrieves data in the domain object or collection,
  • save(), saves (updates existing or inserts new) the domain object or collection
  • remove(), deletes the domain object or collection from storage medium

我将条件保留在域对象本身中:

I keep the condition in the domain object itself:

$user = new User;
$user->setName( 'Jedediah' );

$mapper = new UserMapper;
$mapper->fetch( $user );

if ( $user->getFlags() > 5  )
{
    $user->setStatus( User::STATUS_LOCKED );
}

$mapper->save( $user );

这样,您可以具有多种检索条件,同时保持界面清洁.

This way you can have multiple conditions for the retrieval, while keeping the interface clean.

这样做的缺点是,您需要一个公共方法来从域对象中检索信息以具有这样的fetch()方法,但是无论如何您都将需要它来执行save().

The downside to this would be that you need a public method for retrieving information from the domain object to have such fetch() method, but you will need it anyway to perform save().

没有实现映射程序和域对象交互的不要问" 经验法则的真正方法.

There is no real way to implement the "Tell Don't Ask" rule-of-thumb for mapper and domain object interaction.

对于如何确保您确实需要保存域对象?" ,您可能会想到,它已被

As for "How to make sure that you really need to save the domain object?", which might occur to you, it has been covered here, with extensive code examples and some useful bits in the comments.

如果您希望处理对象组,则应该处理不同的结构,而不是简单的域对象.

I case if you expect to deal with groups of objects, you should be dealing with different structures, instead of simple 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 );

在这种情况下,集合是荣耀的数组,具有接受不同参数的能力,这些参数然后用作映射器的条件.当mapper尝试存储集合时,它还应该让映射器从此集合中获取列表 changed 更改过的域对象.

In this case the collection is glorified array, with ability to accept different parameters, which then are used as conditions for the mapper. It also should let the mapper to acquired list changed domain objects from this collection, when mapper is attempting to store the collection.

在这种情况下,映射器应该能够使用所有可能条件构建(或使用预设的)查询(作为开发人员,您将了解所有这些条件,因此您无需使其可以在无限条件下工作)并为该集合包含的所有未保存域对象更新或创建新条目.

The mapper in this case should be capable of building (or using preset ones) queries with all the possible conditions (as a developer you will know all of those conditions, therefore you do not need to make it work with infinite set of conditions) and update or create new entries for all the unsaved domain object, that collection contains.

注意:在某些方面,您可以说映射器与构建者/工厂模式有关.目标不同,但是解决问题的方法非常相似.

Note: In some aspect you could say, that the mapper are related to builder/factory patterns. The goal is different, but the approach to solving the problems is very similar.

这篇关于谁应该处理复杂查询,数据映射器或服务层中的条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆