Доброго всем времени суток!
Мучает меня последнее время вопрос... прям спать не могу

. Решил поделиться с общественностью — что б тоже сон потеряла.
Итак, что такое многоуровневая архитектура? В моём понимании это такое построение приложения, при котором оно состоит из нескольких слоёв, причём слои верхнего уровня используют слои нижнего, но не наоборот. Классический пример:
Presentation(UI)->Business Logic(BL)->Data Access Layer(DAL)->Storage(DB)
Постулат такой: любые вызовы из нижлежащего слоя к вышестоящему недопустимы. За редким исключением (например callback-и) которых следует таки избегать.
Почему? Достоинство я вижу на самом деле только одно: уменьшается связность. А следствий может быть очень много, как то упрощение юнит-тестирования, повышение потенциальной масштабируемости вширь, и т.п.
В описаном примере думаю очевидным будет тот факт, что вызовы к UI из BL и тем более из DAL — признок дурно пахнущей архитектуры.
(Конечно из всех правил есть исключения, но речь не о них.)
Собственно это была приcказка. Сама же сказка такая:
Реализуем BL на основе
Domain Model. Т.е. бизнес логика приложения содержится в классах, которые являются отражением предметной области. Классы содержат данные и логику работы с ними (инкапсуляция блин, кудаж без неё!).
Реализуем DAL на основе
Data Mapper. Собственно слой предоставляющий интерфейс для работы с хранилищем на основе обектно-ориентированой модели.
И вот что не даёт мне спать по ночам: DAL связан с BL, поскольку выполняет создание экземпляров классов из Domain Model и их инициализацию данными из DB. Налицо вопиющее нарушение "слойности" архитектуры. Анархия. Разруха. Полный капец.
Читал Фаулера. Этот "нехороший человек" обошёл проблемму стороной упомянув что "однозначно хорошего решения не существует".
Собственно какие способы вижу я:
1. Отделение BL от данных и выделение отдельной группы объектов-data-контейнеров. Где же тогда инкапсуляция? Правильно — в Ж.
2. Выделение интерфейсов для Data Mapper и их реализация в классах BL. Но здесь всё равно остаётся проблемма создания экземпляров. Можно разрулить каким-нибудь порождающим паттерном, фабрикой к примеру или даже заюзать IoC engine, reflection в конце концов. Но не все фреймворки реализующие Data Mapper такое позволяют.
Есть у уважаемого сообщества идеи ЕДИНСТВЕННО ПРАВИЛЬНОЙ БОЖЕСТВЕННОЙ АРХИТЕКТУРЫ?
PS Если заюзать на BL Transaction Script к примеру, проблемма исчезает сама собой. Но тот же Фаулер Transaction Script ругает...
PPS Всё вышесказанное есть моё глубокое ИМХО. Если вы считаете иначе — отлично, поделитесь мнением!