Сегодня, вышел новый плагин для IntelliJ IDEA. Плагин позволяет управлять процессом разработки голосом. Скачать его можно от сюда. :)))
Thursday, April 2, 2009
Data Transfer Object - это не лекарство от "болезни" Rich Domain Model.
В последнее время я все более часто встречаюсь с мнением, что Data Transfer Object - это антипаттерн, позволяющий "хоть как-то выживать rich domain model" в суровом мире n-tier приложений и что при использовании анемичной модели эти источники лишней работы вообще не нужны. На деле же выходит, что это совсем не так.
Прежде чем продолжить, уточню способы организации бизнес-логики(поведения и данных) в упомянутых моделях:
Rich Domain Model - поведение распределяется по бизнес-правилам, правилам валидации, спецификациям, стратегиям, доменным сервисам, сущностям, объектам-значениям. Данные в основном хранятся в сущностях и объектах-значениях.
Anemic Domain Model - под этим типом, обычно понимается несколько вариаций организаций бизнес-логики. Классическая - которую сформулировал сам Фаулер, доменные объекты(присутствуют только сущности и объекты-значения, как наборы примитивных данных) не содержат поведения или содержат его недостаточно и основное его скопление находится в сервисах уровня приложения, что делает способ похожим на способы Transaction Script/Table Module, приводящими к процедурному подходу и подходящими лишь для простых приложений. Именно от этого сходства и остерегает нас добрый Фаулер, упоминая, что каждый шаблон призван организовывать свой определенный объем и определенную сложность логики приложения(хотя, формально определить эту величину сложно) .
Но у этого типа анемичной модели есть сразу бросающийся в глаза(вообщем-то Фаулер его и бросает) изъян : зачем помещать бизнес-логику в слой координации, слой сервисов уровня приложения? Многим сразу понятно, что это неправильно, что это нарушает границу логического слоя. Поэтому, появляется частично-анемичная модель, в ней, как правило, есть четкое разделение на доменные объекты содержащие только поведение (бизнес-правила, правила валидации, спецификации, стратегии, сервисы и т.п.) и на сущности и объекты-значения хранящие только данные, но не содержащие поведения).
Скорее всего Фаулер и этот способ назвал бы анемичным, вообщем-то как и Эванс в своей Big Blue Book подчеркивает некорректность данного подхода.
В данной заметке, я специально не хочу сравнивать степень успешности использования того или иного подхода(rich и anemic), поскольку буду это делать в последующих статьях. Здесь, мне хотелось бы начать с опровержения самого простого довода, который приводится в пользу анемичной модели: в анемичной модели не нужны объекты переноса данных.
Так вот, объекты переноса данных, помимо отсоединения и предоставления возможности сериализации данных, необходимы для передачи нескольких элеметов информации за один вызов, причем эти элементы в 90% случаев отличаются своей структурой, от на первый взгляд эквивалентных объектов домена, хранящих состояние(сущностей и объектов-значений).
Мне реально очень сложно найти пример, где необходимо использовать Domain Model в n-tier среде и не нужны Data Transfer Object'ы. Рассмотрим типичную форму "экстенсивно" развивающейся торговой информационной системы:
Даже если проектировать приложение, с расчетом на прототипы экранов пользовательского интерфейса(например на эту форму), вряд ли получится ее разумно реализовать, используя анемичную модель, без объектов передачи данных. И вообщем-то понятно, что даже, если не появится еще несколько типов клиентских приложений к нашей системе, то и в этом приложении обязательно будут придуманы "похожие" формы, использующие данные похожие по структуре на наши сущности, но обязательно отличающиеся от них.
Я допускаю возможность существования n-tier приложений, реализованных без объектов переноса данных, но это либо временное явление, характерное для не до конца сформированных требований, либо приложения со способом организации и инкапсуляции бизнес-логики отличным от способа Domain Model(и парадигмы DDD).
Поэтому, коллеги, используя анемичную модель, тоже не обойтись без объектов переноса данных(Data Transfer Object - DTO).