Гэри МакЛинн - Так ли уж вам нужен ORM?

Object-Relational Mapping (ORM) необходим только если у вас есть - 1) объектная модель 2) необходимость сохранения этой объектной модели в реляционной СУБД (Relational Database Management System или RDBMS). Последнее вполне может быть необходимостью, особенно в веб-приложениях. Однако с первым могут возникнуть вопросы. У вас существует объектная модель, если у вас есть набор полноценных классов, обладающих некими данными (например, в виде полей) и имеющими собственное поведение (например, в виде методов).

Объектно-ориентированный дизайн (Object Oriented Design или OOD) основывается на жесткой связи между данными объектов и методами, оперирующими с этими данными. Без ассоциированного поведения вы остаётесь с анемичной доменной моделью. Всё, что у вас есть - граф объекта с отношениями и данные, замапленные к определённому домену. Но чётко структурированное поведение ограничено считывателями (getters) и установщиками(setters) данных.


Зачастую "бизнес-логика" выделяется в сервисный слой, который управляет объектами на намного более высоком уровне.

Выше я привел UML-диаграмму очень простого вида блогов. Отметьте, что на ней обозначены объекты с именами, соответствующими существительным из проблемной области. Однако, поведения объектов вы тут не найдёте. У объекта User нет глагола Login (войти), CreateCategory (создать категорию) и SubmitComment (отправить комментарий). У объекта Post нет глагола SaveDraft (сохранить черновик) и Publish (опубликовать). У Comment нет глагола Accept (принять) и Flag (отметить).

Это как раз и есть полностью настроенное поведение, которое, скорее всего, будет перемещаться в сервисный слой с высокоуровневой функциональностью. И в этом нет ничего плохого, если мы не говорим об ORM, который занимает место между этим графом объектов и постоянным хранилищем (а не просто о сериализации этого графа объектов).

Поскольку блоги обычно находятся в состоянии онлайн, разумно предположить наличие РСУБД, которая будет использоваться в качестве постоянного хранилища. Это уже половина условия использования ORM. Но здесь ORM точно не нужен, поскольку тут нет доменной модели.

Какова же альтернатива?

Martin Fowler предлагает множество альтернатив в книге "Patterns of Enterprise Application Architecture" - в главе "Data Source Architectural Patterns".

Вместо перечисления высокоуровневых паттернов, уже предложенных Мартином, я лучше перескочу к выбору технологии. Изначально такой технологией был NHibernate, но теперь можно взять более простую ORM, такую как Entity Framework. Генерация кода маппинга намного проще изучения конфигурационных файлов NHibernate. Но даже такой подход может быть отвергнут как излишне сложный.

Возможно, вам подойдёт Active Record, но, опять же, есть подходящая альтернатива, когда поведение находится в самих объектах.

Простейшее решение, которое я мог отстоять, в том случае, когда поведение отсутствует в модели домена - Typed DataSet (типизированный набор данных). Во-первых, типизированный датасет может быть сгенерирован из существующей БД, что приводит к созданию CRUD-операций для всех таблиц, а также к локальному соблюдению ссылочной целостности, без необходимости повторного обращения к БД.

Далее, если это необходимо, неаккуратный автосгенерированный код может быть спрятан за аккуратными интерфейсами для каждого объекта домена путём добавления частичных определений к каждому сгенерированному классу – нужно только смотреть, чтобы имена и типы свойств соответствовали сгенерированным.

То, что мы создаём с помощью этого паттерна, практически является объектами переноса данных (Data Transfer Objects или DTOs) – т.е. практически тем, с чего мы начинали, поскольку DTOs - это объекты безо всякого поведения. Мы лишь допускаем некий факт и принимаем дизайнерские решения, основанные на этом допущении.

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

Перейти к оригиналу.

Комментарии

Популярные сообщения из этого блога

Библиотека расчёта периодов времени для платформы .NET

Маленькие чудеса C#/.NET – структура DateTimeOffset