Как вы не знаю, но я себя на этой картинке узнал. Ведь, согласитесь, когда проектируется архитектура приложения, все красиво, логично и соответствует лучшим мировым практикам. Но в процессе работы, сталкиваясь с ограничениями предъявляемыми архитектурой, мы зачастую думаем: «Вот здесь немножко нарушу, это ведь сэкономит мне час времени разработки. Ну а потом, как будет время, поправлю». Но, почему-то, это время так никогда и не наступает. На мой взгляд, единственным способом заставить себя, как программиста, следовать разработанной архитектуре, это научить среду разработки все отклонения и костыли показывать как ошибки компиляции. В этом случае, если код плох, он сразу будет исправлен, ну а если архитектура устарела, то будет исправлена она. Т.е. в хранилище кода всегда будет код соответствующей запланированной архитектуре.
Пара слов, о том, что будет подкатом:
1. Небольшая преамбула.
2. Восстановление архитектуры по имеющемуся проекту.
3. Настройка Visual Studio и TFS для автоматического контроля архитектуры.
Под катом много картинок и желание все описанное попробовать.
Итак, обещанная преамбула. Почти год назад, Дмитрий Андреев (dmandreev) уже публиковал статью на эту тему. Я эту статью с огромным удовольствием прочитал, и, собственно, именно она меня подвигла заняться вопросом применения Layer Diagram в процессе разработки приложений. Кстати, дочитав до этого места, вы уже сходили по приведенной ссылке и прочитали то, что написал Дмитрий? Нет, ну тогда давайте, я вас подожду, а потом пойдем дальше. Жду.
Ок, теперь когда у нас с вами есть общее понимание Layer Diagram можно заканчивать с преамбулой и переходить к практической работе.
Подготовка демонстрационного проекта
Для демонстрации работы с Layer Diagram, я возьму проект, чуть более близкий к реальности, чем рассмотрел Дмитрий. Пусть у нас будет слой доступа к данным (я буду использовать Entity Framework) и, собственно, слой клиентских приложений в котором также будет слоистая структура (MVVM). В клиентском уровне модель будет браться из первого слоя, а вот слои View и ViewModel будут размазаны по нескольким сборкам.
Вот так, эти четыре проекта выглядят после создания:
Я думаю все, изменяют Namespace по умолчанию для создаваемых сборок? Ну вот, и в этом примере, для 3-х клиентских сборок я заменю Default Namespace:
Добавляем в проект DAL базу данных и Entity Model. В клиентских проектах создаем папки View и ViewModel. Добавляем в них тестовые компоненты и классы:
Добавив ссылки между проектами, обращения между созданными компонентами и классами, можно получить граф зависимостей примерно такого вида:
Если разбиение на слои, идет на уровне сборок, то в связи с запретом на циклические ссылки между сборками (иначе нельзя определить порядок построения), возможна только проблема «обращения через слой» (которая как раз и рассматривается в статье Дмитрия). Если же в проекте, как в данном случае, слои размазаны по нескольким сборкам, причем в рамках одной сборки есть представители разных слоев, перетаскивание проектов/файлов из Solution Explorer-а в Layer Diagram оказывается не эффективным. И тут на помощь приходит Architecture Explorer, который вызывается из главного меню: Architecture -> Windows -> Architecture Explorer. Сразу после открытия он будет иметь вид:
Скажу честно, когда я прочитал про этот инструмент первый раз, я сразу же в него влюбился. Такие возможности для анализа зависимостей, что просто дух захватывает. И хотя про него можно писать очень много и восторженно, так как автоматически контролировать архитектуру он не позволяет, о нем подробнее в другой раз.
Восстановление диаграммы слоев из артефактов решения
Раз сцена готова, выпускаем актеров. Добавляем в решение модельный проект, уже в него добавляем Layer Diagram:
Да, здесь мы можем перетяуть из Toolbox-а слои, нарисовать зависимости, потом долго и упорно в эти слои переносить классы из клиентских проектов. И все это только для того, чтобы уже на следующий день, когда разработчик добавит новый класс, про который мы не знаем, и к слоям он не привязан, а следовательно проверка перестанет работать. Чтобы этого избежать, нам и пригодится Architecture Explorer.
Обратите внимание, что все классы ViewModel оказались в одном пространстве имен (ну пусть в реальном проекте они будут в 3-5), и нам теперь можно в диаграмму слоев добавлять не классы, а целиком пространства имен. Выделяем их и, не создавая никаких слоев, перетягиваем на нашу Layer Diagram:
Кстати, можем воспользоваться и функционалом перетаскивания проектов из Solution Explorer-а. С Shift-ом выделяем в нем ClientApp1, ClientApp2 и Base.Library, хватаем левой кнопкой мыши и перетягиваем на свободное место в Layer Diagram:
Переименовываем новый слой в Presentation, выделяем два слоя (View и View Model) и перетаскиваем их в слой Presentation:
Практически все готово, не хватает только связей. Для того, чтобы их сгенерировать, достаточно вызвать контекстное меню на Layer Diagram-е и выбрать пункт Generate Dependencies:
Теперь, наша диаграмма слоев приняла законченный вид:
Если у вас возникает вопрос, по поводу стрелки от ViewModel к View, то посмотреть мнения на эту тему, а может и принять участие в обсуждении, можно на форуме MSDN.
Автоматический контроль архитектуры
Ну и последний момент, как заставить диаграмму слоев автоматически, при каждом построении проверять, что код соответствует архитектуре? На самом деле достаточно просто. Для демонстрации, я в ClientApp1, в папку View добавлю компонент, который будет напрямую обращаться к слою доступа к данным:
Запускам построение и видим: Build succeeded. Для того, чтобы билды при ошибках архитектуры падали, необходимо открыть свойства модели из Solution Explorer-а (через контестное меню или выбрать и нажать F4) и включить проверку архитектуры:
Еще раз запускам построение и видим, что у нас появились ошибки архитектуры:
Двойной клик на ошибке, сразу привод к месту, в которое забит костыль.
Конечно, проверка зависимостей приводит к увеличению времени компиляции, поэтому можно собрать два решения, одно с которым работают разработчики (в него не включать Modeling Project), а второе, с тем же набором проектов и Modeling Project, для автоматических построений в Team Foundation Server. В этом случае на рабочих местах построение идет быстрее, а контроль архитектуры выполняется на сервере, причем по ошибкам построения, могут сразу генерироваться баги.
Перед тем, как перейти к выводам, небольшая ремарка. Все описанное в данной статье работает и в Visual Studio 2010 и в Visual Studio 2012. Единственно, требуется версия Ultimate или Premium. Если у вас нет лицензии на соответствующие версии Visual Studio 2010, то Release Candidate версию Visual Studio 2012 Ultimate можно скачать здесь.
Выводы
1. Layer Diagram это инструментарий, про который надо как минимум знать, и в новых проектах начинать применять
2. Автоматическая проверка архитектуры позволит снизить количество «костылей» забиваемых в спешке или по не знанию
3. Правильное именование пространств имен и применение Architecture Explorer-а позволяет существенно сократить время на восстановление архитектуры
P.s. Если в данной статье, про что-то и забыл рассказать, то прошу на меня сильно не ругаться, и читать первоисточники: Визуализация существующего кода.
Автор: Teacher