Мой блог

Что такое предел сложности?

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

Нередко в общении с командами разработчиков, я слышу: «Наш продукт невероятно сложен. Мы нанимаем только самых лучших». Для меня же повышенная сложность продукта свидетельствует, в первую очередь, о недостаточной квалификации участников команды. По-настоящему сложно создавать простые продукты. Безусловно, за внешне простым интерфейсом может скрываться огромная инфраструктура из тысяч серверов, но если эту часть тяжело поддерживать, значит что-то сделано неверно.

Предел сложности – это вполне конкретная величина, ее можно определить для каждого проекта. И его превышения следует избегать. В качестве примеров критериев, по которым можно рассчитать предел сложности можно привести:

  • Количество сущностей, которые необходимо учитывать для того, чтобы реализовать новый функционал. Если необходимость добавить кнопку в один интерфейс требует пересмотра механизмов отображения в ряде остальных интерфейсов, значит предел сложности превышен.
  • Глубина вложенности. Количество слоев абстракций, на которое необходимо спуститься вниз, чтобы реализовать заданную функцию. Если для реализации решения уровня UI разработчику приходится модифицировать одну из абстракций уровня ядра, значит предел сложности превышен.
  • Время жизни переменных. Это «расстояние» между инициализацией переменной и ее использованием. Чем оно меньше, тем лучше. Если вам приходится тратить несколько часов на, то чтобы понять в каком модуле переменная получает свое значение, значит предел сложности превышен.
  • В качестве критериев можно использовать максимальный размер функции или максимальный размер модуля. Все эти критерии очень тесно связаны не только с проектированием, но и с практиками написания хорошего, читаемого кода. Это не должно удивлять. Вы не создадите хороший программный продукт, если ваш код тяжело читать.

Практический пример

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

Так выглядят проекты, в которых нет правил взаимодействия подсистем.

А теперь давайте представим, что произойдет, если я захочу, например, изменить структуру нескольких таблиц в базе данных, чтобы повысить быстродействие, упростить запросы и увеличить масштабируемость?

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

Это данность больших и масштабных проектов? Нет. Все можно сделать гораздо лучше.

Так выглядят проекты, у которых продуманы и прописаны правила взаимодействия между подсистемами
  • Непосредственно в базу данных пишут и читают только провайдеры данных.
  • Результаты, которые выдают модули в Бизнес правилах, зависят только от данных предоставленных Провайдером данных и ни от чего больше.
  • Провайдеры состояний хранят только информацию, которая зависит от внешних факторов, несвязанных напрямую с основными данными, которыми оперирует проект.
  • Система связей представляет собой ациклический граф

Очень хорошо тема проектирования и управления сложностью описана в книге Стива Макконелла «Совершенный код» 2-е издание Раздел 5.2 «Основные концепции проектирования» Главный Технический Императив Разработки ПО: Управление сложностью

06 мар.2018