Кто должен обрабатывать условия в сложных запросах, карту данных или уровне обслуживания? - программирование

Кто должен обрабатывать условия в сложных запросах, карту данных или уровне обслуживания?

этот вопрос очень помог мне немного разобраться в моем замешательстве, но мне трудно найти надежные источники о том, какие точные ограничения уровня обслуживания.

В этом примере предположим, что мы имеем дело с книгами, и мы хотим получить книги от автора. BookDataMapper может иметь общий get() метод, который принимает условие (ы), такое как уникальный идентификатор книги, имя автора и т.д. Эта реализация довольно тривиальна (логически), но что, если мы хотим иметь несколько условий, которые требуют более сложный запрос?

Предположим, мы хотим получить всю книгу, написанную определенным автором под определенным издателем. Мы могли бы расширить метод BookDataMapper->get() для анализа нескольких условий, или мы могли бы написать новый метод, например BookDataMapper->getByAuthorAndPublisher().

Желательно, чтобы уровень сервиса вызывал эти [более конкретные] методы напрямую или выполнялись условия перед вызовом более общего метода BookDataMapper->get() с несколькими условиями? В последнем сценарии сервисный уровень будет делать больше логического "тяжелого подъема", оставив карту данных довольно простой. Первый вариант почти полностью сместил бы сервисный уровень только к среднему человеку, оставив условную логику в компоновщике данных в таких методах, как BookDataMapper->getByAuthorAndPublisher().

Очевидная забота о том, чтобы позволить сервисному слою анализировать условия, заключается в том, что часть логики домена протекает из устройства отображения данных. (это объясняется в связанном вопросе здесь. Однако, если сервисный уровень должен был обрабатывать условия, логика не выходила бы из уровня модели; будет вызывать $book_service->getByAuthorAndPublisher() независимо.

4b9b3361

Ответ 1

Шаблон сопоставления данных сообщает вам, что он должен делать, а не как его реализовать.
Поэтому все ответы в этой теме следует рассматривать как субъективные, поскольку они отражают индивидуальные предпочтения каждого автора.

Я обычно стараюсь максимально упростить интерфейс 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" для взаимодействия с картой и доменом.

Что касается "Как убедиться, что вам действительно нужно сохранить объект домена?", который может возникнуть у вас, он был покрыт здесь, с обширными примеры кода и некоторые полезные биты в комментариях.

Update

В случае, если вы ожидаете иметь дело с группами объектов, вы должны иметь дело с разными структурами, а не с простыми объектами домена.

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

В этом случае коллекция представляет собой прославленный массив с возможностью принимать разные параметры, которые затем используются в качестве условий для картографа. Он также должен позволить картографу в приобретенный список изменить объекты домена из этой коллекции, когда сборщик пытается сохранить коллекцию.

В этом случае сборщик должен иметь возможность создавать (или использовать запрограммированные) запросы со всеми возможными условиями (как разработчик вы будете знать все эти условия, поэтому вам не нужно работать с бесконечным набором условия), а также обновить или создать новые записи для всего несохраненного объекта домена, в котором содержится коллекция.

Примечание.. В каком-то аспекте вы можете сказать, что обработчик связан с шаблонами builder/ factory. Цель другая, но подход к решению проблем очень схож.

Ответ 2

Я обычно предпочитаю, чтобы это было более конкретным, например:

BookDataMapper->getByAuthorAndPublisher($author, $publisher)

Это потому, что мне не нужно повторно изобретать SQL. База данных лучше для этого, и картографист данных позаботится о том, чтобы остальная часть приложения не нуждалась в том, чтобы знать что-либо о том, как вещи хранятся или задаются в конкретном случае.

Если вы сделаете это более динамичным, вы можете легко иметь тенденцию предлагать слишком много функций через интерфейс. Нехорошо.

И взгляните на свое приложение. Вы увидите, что не так много будет задаваться по-другому. Для основной части данных, которая обычно составляет около 5-10 подпрограмм, если вообще. Это написано гораздо быстрее, чем даже думать о какой-то динамической системе, которая в любом случае будет принадлежать ей на собственном уровне.