Сколько логики должно быть в объектах модели домена

Просто закончил читать этот пост Грегом Янга, где он говорит о том, что Microsoft рекомендует шаблоны с немыми объектами передачи данных. Он подразумевал, что в сообществе Java все меняется в другом направлении.

Мой вопрос в том, насколько логика должна быть в объектах сущности? Наша философия, в которой я работаю (магазин С#), заключается в том, что если вы не можете ее сериализовать, не помещайте ее в объект.

Ответы

Ответ 1

Матовый,

Я бы сказал, что ваш магазин пишет процедурный код. Я хочу пояснить, что нет ничего плохого в том, что многие крупные системы (включая многие из которых я работал) были написаны с использованием процедурного кода. Для этого есть время и место.

Теперь процедурный код не имеет места в модели домена. Если вы хотите использовать более процедурный стиль, который является прекрасным, но используйте его с чем-то вроде Table Module или Active Record pattern. Это не отсутствие OO, которое я рассматриваю как настолько разрушительное в руководстве, но использование модели домена с процедурной логикой.

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

Теперь, чтобы вернуться к тому, что "является поведением", я хотел бы сосредоточиться на вопросе с объектно-ориентированной точки зрения, а не на точке зрения "Driven Design". Объект, как правило, инкапсулирует какое-то состояние и, как правило, выставляет некоторые виды поведения.

quick reiteration: инкапсулировать состояние, выставлять поведение

Итак, какое поведение должен иметь объект? Проще говоря, это должно быть поведение, которое действует на состояние, которое оно инкапсулирует. В идеальном поведенческом мире ОО государство никогда не будет подвергаться действию только объекта. Поместите тактично в код, если мы начнем видеть код вроде:

Customer c = GetCustomerFromRepository();
c.Status = CustomerStatuses.Deleted;
c.LastUpdated = DateTime.Now;
c.UpdatedBy = GetCurrentUser();
CustomerRepository.Save(c);

У нас есть нарушение SRP... Этот код - это код, который должен быть поведением объекта-клиента, потому что "Ответственность" объекта-клиента есть.

Инкапсулировать состояние клиента и выявить поведение.

Таким образом, мы можем видеть, что нам было бы лучше иметь метод Customer.Delete(). (да, это плохой пример, который я знаю...)

Теперь мы также получим это с помощью TDD. Нам намного легче справляться с испытаниями с помощью шва, которое обеспечивает поведение, чем швы, где открыто все состояние. Причина этого в том, что мне не нужно дублировать логику в моих тестах. Клиентскому коду все равно, как работает удаление... он заботится только о том, что клиент раскрывает поведение. Как таковой в наших тестах, вместо того, чтобы утверждать, что c.State == CustomerStates.Deleted и c.UpdatedBy == GetCurrentUser() и т.д. И т.д., Мы просто утверждаем, что метод удаления был вызван на швом клиента с помощью макета.

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

Помогло ли это немного прояснить ситуацию?

Грег

Ответ 2

Если вы называете их "объектами модели домена", я предполагаю, что вы ссылаетесь на шаблон модели Доклада Фаулера. http://martinfowler.com/eaaCatalog/domainModel.html

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

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

Если вы еще этого не сделали, я бы посоветовал вам прочитать PoEAA и решить, где вы думаете, что логика домена принадлежит вашей ситуации. Если вы решите создать модель домена, я бы посоветовал вам прочитать книгу Evan DDD и узнать о различиях между объектами, объектами ценности и услугами.

Надеюсь, что это поможет!

Ответ 3

Главное, как определить логику. Чтобы привести несколько примеров:

  • Я бы не классифицировал функцию getFullName() в объекте Person, которая просто конкатенирует некоторые строки, как логику.
  • Вычисление значения позиции заказа, скорее всего, будет соответствовать логике.
  • Выполнение некоторых транзакций по бронированию, которые я бы сказал, логично.

Точка 1 и, возможно, 2 пойдет на меня в сущность. Пункт 3 нет. Поэтому я определяю логику как:

  • любая операция, которая выполняет любую связанную с сохранением вещь (чтение/запись)
  • любая операция, которая включает в себя любой другой (не связанный напрямую, например, основной-детали) объект

IMO, любая из этих операций не относится к объектам.

Теперь, почему/когда я не ставил операции типа 1 и 2 типа в объект? Это довольно редкая ситуация, но я бы этого не сделал, как только данные, хранящиеся в объекте, должны быть каким-то образом интерпретированы, прежде чем он сможет использоваться приложением (например, если в зависимости от текущего пользователя содержимое поля X имеет другое значение), что означает, что данные сущности приводят к некоторой логике.

Ответ 4

В последнее время я занимался идеей создания моделей доменов, у которых есть структура, и только те модели поведения, которые являются универсальными для этой модели (т.е. поведения, которые могут использоваться во многих ограниченных контекстах) с методами расширения для поведения, характерного для ограниченный контекст. Это удерживает модели домена близко к DTO (для тех, кто это нравится) и ограничивает использование этой модели домена только разрешенным поведением в ограниченном контексте. Таким образом, это может быть вариант для ответа средней дорожки.:)

Ответ 5

Насколько я понимаю, вся бизнес-логика, связанная с объектом, должна войти в этот объект. Это состоит из любой логики, которая определяет поведение или внутреннюю структуру объекта на основе бизнес-правил системы. Это не должно включать логику представления или логику устойчивости (очевидное исключение относится к шаблону проектирования Active Record), но должно включать такие вещи, как проверка данных, отношения сущностей, конечные машины и другие вещи, которые определяют, как объект ведет себя с точки зрения реального времени, мир, который он пытается моделировать.

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