Должны ли классы данных повторно использоваться в разных слоях и приложениях или отображаться в классы, специфичные для слоев? - PullRequest
8 голосов
/ 08 февраля 2012

Я создаю приложение WPF, которое использует службу WCF для взаимодействия с источником данных. Я использую DI как для клиента, так и для сервера WCF, чтобы обеспечить разделенный код, но я не уверен, как обрабатывать передачу данных из серверной части в пользовательский интерфейс.

Чтобы сохранить слои, отдельные данные в настоящее время передаются из базы данных в пользовательский интерфейс через несколько этапов отображения. На стороне сервера объекты данных отображаются на объекты домена, которые снова отображаются на контракты на обслуживание данных. На стороне клиента прокси-классы WCF отображаются на модели представления.

Некоторые разработчики на работе утверждают, что такое «копирование» данных между, казалось бы, идентичными классами создает проблему обслуживания, поскольку при внесении изменений необходимо обновить очень много классов. Вместо этого они говорят, что вы должны использовать общие классы на всех уровнях, поскольку мы контролируем и клиентское приложение, и службу WCF. Я тоже беспокоюсь об объеме работы и вижу потенциальное снижение производительности, но, с другой стороны, использование общего класса между слоями / абстракциями может создать тесную связь, как я это вижу. Каков наилучший подход?

Ответы [ 3 ]

9 голосов
/ 08 февраля 2012

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

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

Но если это , то это приложение, управляемое данными, когда клиенты получают доступнекоторые данные, измените их и сохраните обратно, тогда, возможно, вам не нужен этот сложный уровень?Звучит просто, так что давайте будем простыми.Если является приложением, управляемым данными, почему бы просто не создать контекст WCF DataServices поверх вашей базы данных и позволить ему выполнять всю грязную работу за вас, когда вы просто получаете доступ к своим даннымнад WCF, даже не задумываясь о DTO, сопоставлениях и т. д.

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

Вместо этого пользовательский интерфейс, вероятно, будет отправлять команды на сервер для запроса системы сделать что-то .Например, он будет отправлять команду «DisableAccount (id = 123)» вместо загрузки AccountDTO, изменяя свой флаг IsEnabled на false и толкая его обратно.Если является бизнес-логикой, то она, вероятно, будет вызвана такой командой от клиента, которому не нужно знать , как отключить учетные записи или какделать другие вещи.Он просто знает и может дать команду системе сделать что-то.

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

Скажем, пользователь для пользовательского интерфейса не является DTO, сопоставленным с таблицей пользователей.Это еще один DTO, содержащий пользовательские данные и статистику из разных таблиц, как-то обработанные.Клиенту не нужно знать внутреннюю структуру хранилища данных на сервере, поэтому нет необходимости раскрывать его.Получите соответствующие данные и отправьте соответствующие команды, вот и все.

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

Вам не нужно выбирать один для всего.Таким образом, вам не нужно всегда создавать 3 похожих объекта только потому, что это «Путь» или всегда пропускать сущности на всем пути до пользовательского интерфейса.Но то, что вам нужно будет , - это четко разделить контексты и определить, какой подход будет использоваться.

В 80% вы, вероятно, получите что-то простое (например, WCF DataServices), и вам не нужно ничего делать, и это хорошо, так как во многих операциях вы просто хотите изменить данные.

Но в других 20% (которые являются «ядром» вашего приложения), где живет настоящая бизнес-логика, - здесь вы можете захотеть такого рода разделения не только для объектов, но и для обязанностей между вашими уровнями..

6 голосов
/ 10 февраля 2012

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

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

Есть как минимум эти альтернативы:

  • Поддерживать строгое наслоение. Стоимость отображения остается, но код не связан.
  • Сборка монолитного приложения. Свернуть все, что можно свернуть. Сделайте это как можно проще. Он будет тесно связан, но может стать настолько простым, что это не будет иметь значения.
  • Сделайте что-то радикально другое, например, создайте приложение CQRS или SOA mashup.

Лично я предпочитаю третий вариант в эти дни.

0 голосов
/ 08 февраля 2012

Я не вижу ничего священного в слоях. Наличие специфичных для слоя версий каждой сущности в модели значительно увеличит количество классов. Это ненужно, на мой взгляд. Это нарушает принцип СУХОГО: зачем повторяться?

Что покупает чистота слоя?

Так что я бы сказал, что лучший способ - обойти эти модельные объекты без страха.

...