Сколько бизнес-логики должно содержать объекты Value? - PullRequest
12 голосов
/ 21 сентября 2008

Один наставник, которого я уважаю, предполагает, что простой бин - это пустая трата времени - что объекты значения «ДОЛЖНЫ» содержать некоторую бизнес-логику, чтобы быть полезной.

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

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

Ответы [ 6 ]

22 голосов
/ 21 сентября 2008

Идея объединения данных и бизнес-логики состоит в том, чтобы способствовать инкапсуляции и предоставлять как можно меньше внутреннего состояния другим объектам. Таким образом, клиенты могут полагаться на интерфейс, а не на реализацию. См. принцип «говори, не спрашивай» и Закон Деметры . Инкапсуляция облегчает понимание состояний, в которых могут находиться данные, проще для чтения кода, упрощает разделение классов и, как правило, упрощает модульное тестирование.

При экстернализации бизнес-логики (обычно в классы «Сервис» или «Менеджер») возникают вопросы типа «где эти данные используются?» и "В каких штатах это может быть?" гораздо сложнее ответить. Это также процедурный способ мышления, заключенный в объект. Это может привести к модели анемичной области .

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

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

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

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

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

6 голосов
/ 21 сентября 2008

Вам лучше назвать их Передать объекты или Объекты передачи данных (DTO) .

Ранее этот же шаблон j2ee назывался 'Value value', но они меняли имя, потому что его путали с этим

http://dddcommunity.org/discussion/messageboardarchive/ValueObjects.html

Чтобы ответить на ваш вопрос, я бы добавил минимальную логику в мои DTO, логику, которая необходима для отображения.

Еще лучше, если мы говорим о веб-приложении на основе базы данных, я бы вышел за рамки базовых шаблонов j2ee и использовал Hibernate или Java Persistence API для создания модели домена поддерживает ленивую загрузку отношений и использует это в представлении.

См. Открыть сеанс в представлении .

Таким образом, вам не нужно программировать набор DTO, и у вас есть вся бизнес-логика, доступная для использования в ваших представлениях / контроллерах и т. Д.

5 голосов
/ 21 сентября 2008

Это зависит.

упс, я только что выболтал клише?

Основной вопрос, который нужно задать при проектировании объекта: будет ли логика, управляющая данными объекта, другой или такой же при использовании / использовании другими объектами?

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

3 голосов
/ 21 сентября 2008

Мое личное предпочтение - поместить всю бизнес-логику в саму модель предметной области, то есть в «истинные» доменные объекты. Таким образом, при создании объектов передачи данных они в основном представляют собой (неизменяемое) представление состояния объектов домена и, следовательно, не содержат бизнес-логики. Они могут содержать методы для клонирования и сравнения, но основная часть кода бизнес-логики остается в объектах домена.

2 голосов
/ 21 сентября 2008

Что сказал Коррос.

Объект значения: = небольшой простой объект, например, деньги или диапазон дат, равенство которого не основано на идентичности.

DTO: = Объект, который переносит данные между процессами, чтобы уменьшить количество вызовов метода.

Это определения, предложенные Мартином Фаулером, и я бы хотел их популяризировать.

1 голос
/ 21 сентября 2008

Я согласен с Панагиотисом: шаблон открытого сеанса в представлении намного лучше, чем использование DTO. Иными словами, я обнаружил, что приложение намного проще, если вы перемещаете свои доменные объекты (или некоторые их составные части) со своего уровня представления вниз.

Тем не менее, это трудно осуществить, потому что вам нужно, чтобы ваша HttpSession совпадала с единицей работы вашего уровня постоянства. Затем вам необходимо убедиться, что все модификации базы данных (т.е. создание, обновление и удаление) являются преднамеренными. Другими словами, вы не хотите, чтобы это был тот случай, когда уровень представления имеет объект домена, поле модифицируется, и модификация сохраняется без намеренного сохранения изменения кодом приложения. Другой проблемой, с которой важно иметь дело, является обеспечение удовлетворительной семантики транзакций. Обычно выборка и изменение одного объекта домена происходит в одном транзакционном контексте, и нетрудно заставить ваш уровень ORM требовать новой транзакции. Для является сложной задачей является вложенная транзакция, в которой вы хотите включить второй транзакционный контекст в первый открытый.

Если вы не против исследовать, как не-Java API решает эти проблемы, стоит взглянуть на Active Record Rails, которая позволяет страницам сервера Ruby напрямую работать с моделью предметной области и обходить ее ассоциации.

...