Для чего это стоит (я разрабатываю на C # .net - но, надеюсь, принципы должны быть полезны для вас) Я определил несколько типов (DTO), которые я использую для обмена данными между бизнесом и данными ярусы; и у меня есть более одного типа на объект / сущность домена. Они определены как простые классы.
Каждый из них построен с учетом конкретной задачи, например:
- У меня есть облегченный тип, предназначенный для заполнения представлений списка (много «строк», но не так много «столбцов»). У меня также есть соответствующий тип коллекции, который содержит любое число из них.
- У меня есть «большая» копия get, которая обычно имеет все свойства рассматриваемой сущности - но только для одного ее экземпляра. У меня может быть более одного из них в зависимости от размера и сложности объекта в зависимости от случаев использования; а также в зависимости от того, хотите ли вы сразу вернуть все данные, связанные с экземпляром объекта, или отложенную загрузку некоторых при последующих запросах.
- У меня также обычно есть отдельные типы «сохранить» (новый) и «обновить» для сущности.
Каждый тип предназначен для хранения только информации, относящейся к данной задаче.
Например, «большой» будет возвращать дату последнего изменения, но я не ожидаю этого в моих типах сохранения и обновления, потому что я заполняю их на уровне доступа к данным.
Кроме того, для моего приложения эти типы существуют в общей сборке, поэтому их можно повторно использовать между любыми уровнями, а не только между уровнями бизнеса и данными.
Архитектурная форма
В этом подходе нет ничего особенного, у него есть свои плюсы и минусы; что именно это и как они влияют на вас, будет зависеть от многих вещей - я полагаю, ваш пробег будет разным - но он определенно хорошо служил мне в течение ряда лет.
Люди часто суетятся из-за "разделения интересов" - и это действительно мудрый шаг; это относится к DTO в том смысле, что они обмениваются между уровнями (и сервисами, компонентами и т. д.), поэтому всегда может быть некоторая неоднозначность относительно того, где именно провести линию.
Я придерживаюсь подхода, что если часть информации подходит для обмена между уровнями, то, вероятно, она подходит для обмена между любым числом уровней - так почему бы не сделать ее доступной для всех? Это также избавляет от необходимости повторно передавать информацию, если вы просто передаете ее.
Что касается сложности, то есть два способа справиться с этим:
- Используйте подробное / удобочитаемое соглашение об именах для всех; типы, чтобы вы знали, что это такое; не имеет значения, сколько их - это то, для чего нужен intelli-sense (& docs). Чем интуитивнее, тем лучше.
- KISS - будь проще, если можешь; вам придется сбалансировать разумное повторное использование и принцип единой ответственности (SRP).
Вы бы создали DTO сложного свойства основного объекта?
Я обнаружил, что делаю DTO по одной из двух причин:
- Есть данные, которые, как я знаю, мне нужно раскрыть (подтолкнуть), и дизайн DTO не представляет никакой сложности: он основан на данных, которые я хочу раскрыть.
- Потяните: потребитель знает, чего он хочет, и DTO разработан для удовлетворения этих потребностей.
Поскольку все они определены в общей сборке, ни один компонент не «владеет» ею, это помогает вам думать с точки зрения «домена», а не с точки зрения компонента; в некоторой степени это повлияет на структуру DTO (повторное использование баланса против SRP).
В обоих случаях сделанный DTO может быть специфичным для конкретной потребности или общим; например, DTO, в котором есть только int и строка, не редкость, это то, что вы бы использовали для отправки в выпадающие списки.
Большинство коллекций DTO, которые я отправляю (от DAL до BL), являются специфическими для концепции - не являются общими. Я применяю очень простые правила для них с помощью конструкторов, которые я предлагаю: требуется каждый аргумент. Я не уверен, отвечает ли это на ваш вопрос «Как вы управляете сборкой и проверкой».