Рекомендации по архитектуре веб-приложений - PullRequest
0 голосов
/ 27 марта 2012

Команда, с которой я работаю (3 человека), в настоящее время обсуждает архитектуру нового веб-приложения среднего размера, и, как вы можете себе представить, в команде существуют разные мнения о том, как следует разрабатывать приложение. То, что я пытаюсь сделать, - это опубликовать некоторые из этих идей с преимуществами / недостатками для каждого из известных нам подходов, чтобы сообщество SO могло помочь нам выбрать оптимальный путь и / или достичь компромисса.

Архитектура A:

  1. Слой репозитория:

    Звонки в Entity Framework

  2. Уровень обслуживания / бизнеса:

    • У каждого «менеджера» есть интерфейс
    • Каждый «Менеджер» должен иметь 2 реализации (1 макет / 1 факт)
    • Методы в классах Manager для вызова репозитория и последующего применения бизнес-логики
    • Каждый метод для юнит-тестирования
  3. Уровень представления (MVC):

    • Менеджеры, которые будут созданы с помощью некоторого шаблона Service Locator
    • На каждом контроллере должны быть написаны юнит-тесты

Архитектура B:

  1. Уровень обслуживания / бизнеса:

    • Содержит только конкретные классы «Менеджер»
    • Методы вызывают Entity Framework напрямую (например, мы рассматриваем EF как репо)
    • Интерфейсы могут использоваться, но только там, где есть необходимость в различных реализациях
    • Юнит-тесты как и когда требуется

2. Уровень представления (MVC):

  • Менеджер классов, которые будут созданы напрямую
  • Модульное тестирование только хрупкого или значительного кода

Некоторые предположения, которые вы можете сделать:

  • Большинство методов в приложении - это вызовы базы данных с нечетным битом аутентификации / ограничения данных, возвращаемых на основе разрешений пользователя / etc
  • 95% контроллеров не содержат значительной сложности
  • Нет необходимости менять бизнес или иметь разные реализации классов бизнес-уровня. Бизнес рад принять удар по рефакторингу в маловероятном случае, когда нам придется переключать базы данных / etc
  • Предполагаемый размер кода, включая разметку и т. Д., Составляет около 50 тыс. Строк (на основе предыдущей версии веб-приложения, которая является беспорядком)
  • Время разработки невелико
  • Есть специальный QA человек

Извините, если это не так, но моя предпочтительная архитектура на самом деле B по ряду причин.

  1. Я работал над проектами, абстрагированными до n-й степени, и для внесения изменений в каждый из уровней требуется гораздо больше времени, перестраивается в VS, пересматривается методики tests / mock / etc и он предлагает не так много отдачи для проектов, которые по сути являются простыми приложениями CRUD

  2. Бизнесу все равно, если приложение имеет самую чистую архитектуру в мире, он просто хочет быстро доставить продукт без особых ошибок

  3. Для подавляющего большинства методов (на всех уровнях) достаточно простого функционального теста. Если метод GetProductById не работает, исправьте это! На мой взгляд, метод модульных тестов, содержащий больше строк кода, чем тестируемый, просто не требуется для простых методов.

  4. Я хочу иметь возможность щелкнуть правой кнопкой мыши метод, выбрать «Перейти к определению» и увидеть фактический источник метода! Я не хочу видеть определение интерфейса, а затем искать фактический метод в другом месте. Конечно, если все используют интерфейсы, то переключение на другую базу данных * должно быть легким, но реально этого просто не произойдет, и вряд ли это произойдет для этого проекта.

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

У кого-нибудь есть какие-либо предложения / советы?

Ответы [ 3 ]

1 голос
/ 28 марта 2012

Архитектура A

1) Уровень репозитория: вызовы Entity Framework

Абстрагирование OR / M - хороший способ сделать тестируемые зависимые классы (SL / BL).

2) Сервис / бизнес-уровень: - У каждого «менеджера» должен быть интерфейс. - У каждого «менеджера» есть 2 реализации (1 макет / 1 факт). - Методы в классах менеджера для вызова репозитория, а затем для применения бизнес-логики. - Каждый метод для проверки на единицу продукции

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

3) Уровень представления (MVC): - Менеджеры, которые будут созданы с помощью какого-либо шаблона Service Locator - Каждый контроллер должен иметь написанные для него модульные тесты

Расположение службы скрывает зависимости. Вместо этого используйте Dependency Injection (сегодня самый простой подход - использовать контейнер Inversion Of control)

Архитектура B

1) Сервисный / бизнес-уровень: - Содержит только конкретные классы «Менеджер» - Методы напрямую вызывают среду Entity (например, мы рассматриваем EF как репозиторий) - Интерфейсы могут использоваться, но только там, где есть необходимость в различных реализациях - Юнит тесты как и когда требуется

Конечно. Вы можете издеваться над EF4, но гораздо сложнее проверить правильность всех вызовов. Unit tests as and when when required. Так должно быть всегда. Зачем тестировать то, что не нуждается в тестировании. Политика компании, указывающая, когда и что проверять, должна всегда существовать.

2) Уровень представления (MVC): - классы диспетчера, которые должны быть созданы напрямую - модульное тестирование только хрупкого или значительного кода кода

Создание классов напрямую затрудняет определение области видимости. Как вы создаете сложные графы объектов? Он предлагает вам сделать классы менеджера богами или создать высокую связь между классами.

Вопросы

1) Я работал над проектами, которые абстрагированы до n-й степени, и для внесения изменений в каждый из уровней требуется гораздо больше времени, перестраивается в VS, пересматривается методики tests / mock / etc и он не предлагает большая отдача за проекты, которые по сути являются простыми приложениями CRUD

Очень немногие приложения являются CRUD. Приложения Crud не проверяют модель больше, чем проверяют правильность синтаксиса. Эти приложения будут содержать много данных, которые недопустимы с точки зрения бизнеса (но действительны при правильном форматировании)

2) Бизнесу все равно, если приложение имеет самую чистую архитектуру в мире, он просто хочет быстро доставить продукт без особых ошибок

Через несколько лет им все равно, когда техническое обслуживание обошлось безумно.

3) Для подавляющего большинства методов (на всех уровнях) достаточно простого функционального теста. Если метод GetProductById не работает, исправьте это!

Что вы делаете через шесть месяцев, когда вводите новое изменение / функцию? Заставить пользователей протестировать все, что может повлиять на ваши изменения? Поскольку вы не можете * т, если GetProductById не работает, пока вы не протестируете его.

По моему мнению, метод простых тестов, содержащий больше строк кода, чем тестируемый, просто не требуется для простых методов.

imho, этот метод нуждается в рефакторинге и разбит на более мелкие методы. Методы, которые трудно проверить, скорее всего пахнут.

4) Я хочу иметь возможность щелкнуть правой кнопкой мыши по методу, выбрать «Перейти к определению» и увидеть фактический источник метода! Я не хочу видеть определение интерфейса, а затем искать фактический метод в другом месте.

Это меня пугает.Готовы ли вы жертвовать качеством кода только потому, что ваша IDE вам не помогает?Купите резарпер и вы получите «Перейти к реализации».Resharper прошел много проверок качества программного обеспечения, оно того стоит.

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

Это не происходит ни в одном проекте и не является причиной использования интерфейсов.Четко определенные интерфейсы значительно упрощают рефакторинг кода и следуют принципам SOLID.

0 голосов
/ 28 марта 2012

Я согласен с тем, что говорит jgauffin, но я бы хотел кое-что добавить, поэтому я использую его шаблон для единообразия:

Архитектура A

1) Уровень репозитория: вызовы Entity Framework

Как очень хорошо сказал jgauffin, абстрагирование O / RM - это a хороший способ сделать тестируемый BL, на самом деле я бы сказал, что это лучший способ для модульного тестирования вашего BL , что в целом важно. Помните, однако, что есть адвокат, которые говорят, что вы не должны скрывать O / RM за репозиторием по нескольким причинам. Из этого сообщения в блоге:

Проблема с этим шаблоном заключается в том, что он полностью игнорирует существование зрелых технологий персистентности, таких как NHibernate. NHibernate уже обеспечивает иллюзию доступа к памяти, фактически, это его единственная причина существования. Декларативные запросы, проверка. OO посмотреть на персистентность магазина, проверить. Проверьте одностороннюю зависимость между доменом и хранилищем данных.

Итак, что я получу, используя шаблон хранилища, когда у меня уже есть NHibernate (или аналогичный, большинство OR / M уже имеют возможности сопоставления)?

Дебаты все еще открыты, так что это ваш звонок. С помощью NHibernate вы все еще можете тестировать BL, имитируя ISession, я не знаю, как он работает с EF: в качестве альтернативы вы можете протестировать свой BL с интеграционными тестами, работающими с базой данных в памяти (такой как SQLite).

2) Сервис / бизнес-уровень: - У каждого «менеджера» должен быть интерфейс. - У каждого «менеджера» есть 2 реализации (1 макет / 1 факт). - Методы в классах менеджера для вызова репозитория, а затем применения бизнес-логики. - Каждый метод для проверки на единицу продукции

jgauffin говорит, что вы не должны вставлять насмешки в свой BL, и он прав, но пока ваши насмешки находятся в дополнительном проекте, я вижу только преимущества во время интеграционного тестирования, особенно если вы используете сервисы WCF: тогда вы могли бы иметь разные конфигурации (или вообще не иметь конфигурации с обнаружением, только области) для макетных и реальных сервисов и тестировать свои сервисы на нескольких конфигурациях.

3) Уровень представления (MVC): - Менеджеры, которые будут созданы с помощью какого-либо шаблона Service Locator - Каждый контроллер должен иметь написанные для него модульные тесты

Есть люди, утверждающие, что Service Locator является антипаттерном , и аргумент довольно убедителен, даже если иногда оды Service Locator выглядят как меньшее зло. MVC предлагает более элегантные решения для Dependency Injection по сравнению с WebForms, поэтому вам обязательно стоит взглянуть на это.

Архитектура B

1) Сервисный / бизнес-уровень: - Содержит только конкретные классы «Менеджер» - Методы напрямую вызывают среду Entity (например, мы рассматриваем EF как репозиторий) - Интерфейсы могут использоваться, но только там, где есть необходимость в различных реализациях - Юнит тесты как и когда требуется

Как уже говорилось ранее, теоретически это может легко работать с интеграционными тестами с использованием базы данных в памяти, если она достаточно быстра для вас.

2) Уровень представления (MVC): - классы диспетчера, которые должны быть созданы напрямую - модульное тестирование только хрупкого или значительного кода кода

Единственное преимущество, которое я вижу, когда я не использую Контейнер IoC, состоит в том, чтобы иметь одну менее подвижную часть; хотя для целей тестирования я все еще использовал бы DI, так что вы действительно хотите ввести свои зависимости вручную, в стиле DI для бедного человека, для проекта среднего размера?

Резюме

Короче говоря, всегда есть середина, и мы не можем принять это решение за вас. Будучи проектом среднего размера, я бы склонялся к чему-то похожему на архитектуру А; единственное исключение - если это был недолговечный проект, где у вас есть определенная дата, когда ваше приложение устарело и будет закрыто (представьте приложение для определенного неповторяющегося события).

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

0 голосов
/ 27 марта 2012

Мне кажется вполне понятным в соответствии с потребностями бизнеса, что вам следует просто писать код самым простым способом, и я бы пропустил весь материал TDD и вместо этого использовал бы этого выделенного специалиста по тестированию и пропустил формальные объявления интерфейса, кроме случаев, когда они имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...