Концепции DDD в разработке N-уровня
Проведя несколько месяцев, изучая методологию DDD, я теперь начал применять эти концепции в реальных продуктах в своей компании. Фактически, мне было поручено создать подходящую и поддерживаемую архитектуру для будущей разработки.
Мы решили использовать следующие технологии: EF4 (действительно v2), Unity
Количество информации, которую я получил, было наиболее полезным, однако в лучшем случае у меня осталось несколько вопросов:
Вопрос № 1: DTOs - лучшие практики
У меня есть объекты домена (классы POCO). Существует несколько способов реализации этих классов.
- Традиционный подход: создайте классы POCO, которые содержат общедоступные геттеры/сеттеры, валидацию и соответствующую бизнес-логику. Также создайте DTO и используйте методы сопоставления для их управления. (Automapper)
- Традиционный - DTO: Создайте классы POCO, как указано выше, однако используйте свои POCO в качестве объектов переноса. Я понимаю, что бизнес-объекты никогда не должны покидать домен, хотя.
- Гибрид: я наткнулся на интересный сообщение в блоге, в котором автор создает свои объекты POCO и DTO. Внутри своего объекта домена он создает экземпляр DTO. Это позволяет упростить обслуживание, поскольку вы не дублируете свои свойства, как в # 1. Например:
public abstract class POCOBase<T> : ValidationBase, IPOCO where T : DTOBase, new()
{
public T Data { get; set; }
public POCOBase()
{
Data = new T();
}
public POCOBase(T dto)
{
Data = dto;
}
}
public class SomePOCO : POCOBase { }
public class SomeDTO : DTOBase
{
public String Name { get; set; }
public String Description { get; set; }
public Boolean IsEnabled { get; set; }
}
// EXAMPLES
// POCOBase<SomeDTO> somePOCO = new SomePOCO();
// somePOCO.Data.Name = "blablabla";
// somePOCO.Validate();
// return somePOCO.Data;
Вопрос № 2: Какие объекты должны быть возвращены на уровне пользовательского интерфейса/службы?
В этом весь смысл DTO. Очень простой, легкий объект, содержащий только голые атрибуты. Он также не содержит никаких результатов валидации. Если я буду сериализовать свои DTO обратно к клиенту, следует предположить, что клиенту нужны любые результаты валидации, такие как коллекция InvalidRules.
Например, скажем, я работаю с API Amazon. Я хотел бы добавить книгу в свой личный магазин. Если я попытаюсь добавить книгу без отправки своего ISBN, служба, вероятно, вернет некоторую группу ответов, содержащую ошибки результатов проверки.
Я что-то упустил? Я был под впечатлением (по крайней мере от DDD "пуристов" ), что DTO не должны содержать никакой бизнес-логики. Мне кажется, что DTO не предоставляют достаточную информацию в качестве объектов передачи. Либо мне, либо мне нужен новый тип объекта Response, который инкапсулирует результаты DTO и Validation.
Вопрос № 3: Сколько IoC слишком много?
Мне кажется очевидным, что я должен следовать золотому правилу:
"Определите части приложения которые различаются и отделяются от этих которые остаются прежними".
Для меня это имеет смысл с точки зрения применения IoC. Чтобы уменьшить зависимости, мои уровни Presentation, Business Logic и Data Access все взаимодействуют через контейнер IoC. Уровень моего приложения содержит общие интерфейсы и абстракции. Кажется, излишне использовать IoC намного больше, чем это. Мне нравится, что я могу создать тестовые репозитории - и, просто меняя конфигурацию Unity, я могу использовать TDD.
Надеюсь, я четко изложил эти вопросы. Спасибо за вашу помощь заранее!
Ответы
Ответ 1
Я постараюсь ответить на ваши вопросы по очереди.
Ответ 1
DTO ортогональны DDD, потому что они служат другой цели в другом месте архитектуры приложения. Тем не менее, DTO не имеют места в доменной модели, потому что они не имеют поведения и, таким образом, приводят к "Модели анемичных доменов" .
POCOs с сохранением Незнание - это путь. У Джереми Миллера есть хорошая статья в которой объясняется эта концепция.
Ответ 2
Слои, которые сидят поверх модели домена, часто должны возвращать свои собственные объекты, специально предназначенные для этой цели.
Для пользовательских интерфейсов шаблон MVVM работает особенно хорошо. В этой статье представлен MVVM для WPF, но шаблон также работает как прелесть в ASP.NET MVC.
Для веб-сервисов применяется шаблон DTO. Контракты данных WCF - это DTO, если вам интересно:)
Для этого потребуется много сопоставления между интерфейсом службы и моделью домена, но это цена, которую вы должны заплатить за Supple Design. Вы можете найти AutoMapper, полезный в этом отношении.
Ответ 3
Чем больше IoC (действительно: DI), тем лучше, но одна вещь о вашем вопросе поразила меня: контейнер DI должен только подключать график объекта, а затем убираться с пути. Объекты не должны полагаться на контейнер DI.
Подробнее см. этот ответ..