Многоуровневая архитектура - вопросы ответственности
Я разрабатываю приложение, которое реализует многоуровневый шаблон, где MySQL используется для сохранения. Существует служба WCF, которая обеспечивает доступ к данным и обеспечивает DTO.
Кроме того, я планирую реализовать следующие шаблоны: - DTO - MVP (пока не уверен, что пассивный просмотр или наблюдение за контроллером) - Код против интерфейсов, где это применимо
В настоящее время у меня есть следующая структура проекта:
+-------------------------------+
| MySQL DB Server |
+------+------------------------+
^
| Uses Entity Framework 5.0
|
+
+-------------------------------------------------------------------------------+
| Application Server |
|-------------------------------------------------------------------------------|
|+------------------+ +----------------+ +--------------+ +--------------------+|
|| Data Access Layer| | Contracts | | Communication| | Business Layer ||
||------------------| |----------------| |--------------| |--------------------||
|| - EF 5.0 Entities| | - WCF Contracts| | - WCF Service| | - Actual Service ||
|| | | | | Hosts | | - Session management|
|| | | | | | | - Security and ||
|+------------------+ +----------------+ +--------------+ +--------------------+|
+-------------------------------------------------------------------------------+
^
| Communicates via DTOs which are acutally wrappers for Entities
| eg. GetUserByID() or SaveUser(userDTO)
|
|
+-------+-----------------------------------------------------------------------+
| Clients |
|-------------------------------------------------------------------------------|
|+-------------------+ +-------------------+|
|| Business Layer |+----------------------------------->| GUI (Winforms) ||
||-------------------| BLL receives DTOs and creates |-------------------||
|| -Provide WCF Servi| Domain Objects (eg. User) which are| -Implementation of||
|| ce Access | Processed by presenters and passed | View Interfaces ||
|| -Service Reference| to views where they are bound to | ||
|| -Implementation of| controls. | ||
|| Presenter Interf.| | ||
|+-------------------+ +-------------------+|
+-------------------------------------------------------------------------------+
+------------------------------------------------------------------------+
| General |
|------------------------------------------------------------------------|
|+---------------------+ +--------------------+ +-----------------------+|
|| DTOs | | Interfaces | | Library ||
||---------------------| |--------------------| |-----------------------||
|| -DTO Definitions | | -View Interfaces | | -General Helper Classe||
|| | | -Presenter Interf. | | s eg. Cryptography ||
|| | | -Domain Model IF. | | ||
|+---------------------+ +--------------------+ +-----------------------+|
+------------------------------------------------------------------------+
Внешние блоки - это папки проекта в Visual Studio. Внутренние рамки - C# Projects
Прежде чем я продолжу программировать и потрачу больше времени на фактическую реализацию, я просто хотел бы получить некоторые отзывы о структуре / архитектуре моего проекта.
Я оборачиваюсь вокруг следующих вопросов:
- Является ли указанная выше структура "наилучшей практикой"? например. расположение интерфейсов, DTO
- Можно ли иметь два бизнес-уровня или лучше разделить бизнес-уровень на клиент и сервер? Сервер BLL предназначен для обеспечения общих функций, таких как управление сеансом и безопасность, а клиент BLL обеспечивает доступ к сервису. Он также контролирует взгляды своих докладчиков.
- Серверная сторона в настоящее время не знает об объектах домена. Было бы лучше использовать их здесь? Это приведет к сопоставлению моих сущностей с объектами домена, а затем с DTO
- Является ли обычным получение DTO от службы WCF или я должен использовать доменные объекты (я знаю, что это много обсуждалось здесь, но, насколько я понимаю, это было бы применимо, если бы доменные объекты не были такими сложными и могли бы сохранить отображение и кодирование efford при изменении моих доменных объектов и базы данных) Не приведет ли это к очень сложной для поддержания цепочке связи, такой как: Entities<->Domain Object<->DTO<->Domain Object
- Где вы положили подтверждение? Я думал поставить базовую проверку в представлениях или презентаторах (например, форматирование, нулевые / не нулевые значения, ...), в то время как основная проверка относится к объектам домена...?
- При создании новой записи в базе данных, скажем, нового пользователя, должен ли клиент также передавать новый DTO на сервер или лучше создать метод службы, который принимает простые типы данных, такие как string и int?
Извините за этот длинный пост, но я думаю, что было бы лучше объединить мои вопросы в один пост и представить структуру проекта внутри.
Заранее спасибо за любой ответ.
С уважением
2 ответа
Предлагаемая вами структура очень похожа (mutatis mutandis) на одно из наших приложений, которое было развернуто в производстве 2 года назад. Это работает, но вы должны тщательно спроектировать модель предметной области, разделяя в разных ограниченных контекстах различные аспекты приложения.
Так что это мои собственные ответы:
- Нет, здесь нет "лучших практик", чтобы соответствовать. После 5 лет практики DDD в финансовых приложениях, я считаю, что DDD по-прежнему остается исследовательской областью. Тем не менее, это очень хорошо получается, если правильно применять к проектам, ценность которых находится в опыте эксперта в области. Однако вы должны различать бизнес-требования (относящиеся к области) и технологические требования (которые могут помочь в составлении компонентов и уровней, необходимых для вашего приложения).
- Бизнес-уровень (если вам необходимо его идентифицировать) должен обрабатывать только бизнес-правила. Это слой моделей предметной области в приложении DDD.
- По моему опыту, если вы можете доверять клиентской машине и правильно проектировать модель домена, вам вообще не нужен сервер приложений. Однако, если вам это действительно нужно (например, из-за того, что клиенты не могут подключиться к БД), я бы сделал это как можно проще и без сохранения состояния. Здесь полезно учитывать, что в большинстве случаев бизнес-правила уже запрещают одновременный доступ к изменяемым объектам. Не пытайтесь обрабатывать параллельный доступ к таким объектам в этом случае, просто создайте механизм взаимного исключения.
- Для связи между процессами используйте только DTO. Однако вы можете переместить весь домен на сервер приложений (который станет намного сложнее и сложнее) и использовать более простой шаблон MVC на клиенте. Это проще с точки зрения разработчика клиента, но в целом дороже (в частности, его трудно масштабировать).
- Простая проверка типа входных полей может быть выполнена в представлении (целые числа, время и т. Д.), Но вы должны смоделировать каждый соответствующий тип значения с помощью объекта пользовательского значения перед передачей его в домен. Например, вы никогда не должны передавать строки или десятичные числа в доменные объекты, кроме электронной почты или денег. Более того, домен является единственным ответственным за бизнес-инвариант: он должен выдавать выразительные исключения, когда операция не может быть выполнена.
- DTO более выразительны, поэтому их легче отлаживать.
Прежде чем начать, я думаю, вы должны задать себе несколько вопросов:
- Нужен ли мне эксперт по предметной области, или я могу узнать достаточно о бизнесе, читая Википедию или набор хорошо написанных спецификаций? Совет: не нужно (по крайней мере) эксперта по домену == нет необходимости в DDD.
- Могу ли я доверять машинам, на которых будет развернут клиент? Если вы не можете, вам следует рассмотреть возможность перемещения домена на сервер приложений (и принять клиентскую сторону шаблона MVC для обработки запросов WCF и привязок DTO).
Наконец, если вам действительно нужен DDD, и вы новичок в этом, вы можете найти шаблоны моделирования Epic полезными (отказ от ответственности, я один из разработчиков Epic, и я разработал их все в течение последних 5 лет проб и ошибок DDD).
Я отвечу один за другим
1) Зависит от сложности приложения. Если вы работаете со сложным доменом, хорошо следовать дизайну, ориентированному на домен
2) Если вы говорите BLL, он должен заботиться только о бизнес-логике, а не о технических деталях, таких как сеанс, безопасность.
3) Хорошо иметь доменные объекты на стороне сервера. Это способствует повторному использованию
4) Вы не должны выставлять доменные объекты снаружи. DTOs - лучший вариант. Вы можете использовать Automapper для всей работы, связанной с отображением
5) Хорошо иметь проверки в каждом компоненте в зависимости от области применения.
6) DTO лучше
Кроме того, вы можете использовать Service stack, чем WCF, так как он основан на лучших отраслевых практиках.