Бизнес-объекты - Контейнеры или функциональные?

Где я работаю, мы неоднократно возвращались на эту тему и искали проверку здравомыслия. Здесь вопрос: должны ли бизнес-объекты быть контейнерами данных (более похожими на DTO) или должны также содержать логику, которая может выполнять некоторые функции для этого объекта.

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

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

В другой строке рассуждений нет, если у меня есть объект клиента, я просто хочу вызвать Customer.Save и покончить с этим. Зачем мне нужно знать, как сохранить клиента, если я использую этот объект?

Наши последние два проекта имели объекты, отделенные от функциональности, но дискуссия снова была поднята по новому проекту. Что имеет смысл?

ИЗМЕНИТЬ

Эти результаты очень похожи на наши дебаты. Один голос с той или иной стороны полностью меняет направление. Кто-нибудь еще хочет добавить свои 2 цента?

ИЗМЕНИТЬ

Несмотря на то, что выборка ответов невелика, похоже, большинство считают, что функциональность бизнес-объекта приемлема, если она проста, но персистентность лучше всего размещается в отдельном классе/слое. Мы попробуем это. Спасибо всем за вклад...

Ответ 1

Объекты - это состояние и поведение вместе. Если у объекта есть разумное поведение (например, расчет возраста для Лица с даты рождения или общий налог на Счет), обязательно добавьте его. Бизнес-объекты, которые являются не чем иным, как DTO, называются "модель анемичного домена". Я не думаю, что это требование дизайна.

Настойчивость - это особый вид поведения. То, что я называю "разумным", - деловое поведение. Бизнес-объект не должен знать, что он постоянный. Я бы сказал, что DAO может сохранять постоянство отдельно от поведения бизнеса. Я не помещаю "save" в "разумную" категорию.

Ответ 2

Бизнес-объекты МОЖЕТ иметь бизнес-функциональность.

Стойкость не является бизнес-функциональностью, но является технической реализацией.

Короче говоря:

  • Сохранить/обновить/удалить/найти и т.д. - держаться подальше от бизнес-объектов в уровне сохранения.
  • CalculateSalary, ApplyDiscount и т.д. - это связанные с бизнесом методы и могут быть:
    • методы бизнес-объектов (поэтому BO является самодостаточным представлением сущности) или;
    • отдельные службы, реализующие определенную функциональность (поэтому BOs действуют скорее как DTO).

Что касается точки 2.
Следует упомянуть, что подход 2.1 имеет тенденцию к тому, что BO слишком раздуты и нарушают SRP. В то время как 2.2 вводит дополнительное обслуживание сложность.

Я обычно балансирует между 2.1 и 2.2, поэтому я помещаю тривиальные вещи, связанные с данными в Business Objects, и создаю услуги для более сложного сценария (если есть более 4 строк кода - сделайте это услугой).

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

Но это все упрощает разработку, тестирование и поддержку проекта.

Ответ 3

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

Для каждого класса ответ может быть другим. Мы получаем спектр, по которому мы можем размещать классы на основе Плотности ответственности.

                          (Level of responsibility for behavior)
         Autonomy - - - - - - - - - - - - - - - - - - - Dependence  
      High
  C      -   <<GOD object>>                            <<Spaghetti code>>
  l      -
  a      -  
  s      -                                      
  s      -                 
         -                        
  s      -  
  i      -  
  z      -
  e      -  <<Template>>                                <<Framework>>
       low  

Предположим, вы одобряете, позволяя классу выполнять все поведенческие действия, или сколько угодно. Начиная с левой стороны этого графика, когда вы сделаете свой класс более автономным, размер класса будет расти, если вы не будете постоянно реорганизовывать его, чтобы сделать его более общим. Это приводит к шаблону. Если рефакторинг не выполняется, temdency для класса становится более " богоподобным", потому что если есть какое-то поведение, которое ему нужно, у него есть метод для этого. Количество полей и методов растет и вскоре становится как неуправляемым, так и неизбежным. Поскольку класс уже делает так много, кодеры скорее добавят к чудовищу, чем попытаются разделить его и разрезать гордиев узел.

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

Ключом к этому вопросу является определение того, где вы чувствуете себя более комфортно на графике. В любом случае отдельные классы будут распределены по графику, если не будет применен какой-либо организационный принцип, который позволяет достичь результатов Шаблона или Рамки.. p >

Только что написав это, я бы сказал, что существует корреляция между размером класса и степенью организации. Роберт С. Мартин (или "Дядя Боб" ) охватывает аналогичную почву с зависимостями пакетов в своей очень полной статье "Принципы проектирования и шаблоны проектирования" . JDepend - это реализация идей, стоящих за графиком на стр. 26, и дополняет инструменты статического анализа, такие как Checkstyle и PMD.

Ответ 4

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

Возможно, это связано с тем, что я считаю базу данных "контейнером данных", поэтому я выступаю за "бизнес-объекты", являющиеся более высоким уровнем, который защищает контейнер данных от прямого доступа. И применяет стандартные "бизнес-правила" о как эти данные получают доступ/манипулируют.

Ответ 5

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

Ответ 6

Бизнес-объекты должны быть связаны с инкапсулированием данных и связанных с ними поведения бизнес-объекта, смоделированного этим объектом. Подумайте об этом так: одним из основных принципов объектно-ориентированного программирования является инкапсуляция данных и связанных с ними поведения на эти данные.

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

В другой строке рассуждений нет, если у меня есть объект-клиент, я просто хочу вызвать Customer.Save и сделать с ним. Зачем мне нужно знать, как сохранить клиента, если я использую этот объект?

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

Ответ 7

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

С другой стороны, может ли BO быть состав и методы контейнера данных (DTO?); значение BO являются чисто функциональными? Это могло бы избежать всех преобразований между BO и DTO.

Ответ 8

В архитектуре MVC

Можно ли сказать, что модель содержит бизнес-объекты.