Введение

Я делюсь своими заметками о «сложности» — концепции, с которой мы часто сталкиваемся при разработке приложений и продуктов.

Принципы SOLID, Проектирование на основе предметной области, Разработка на основе тестирования, KISS, DRY, YAGNI и т. д. Когда ставятся под сомнение концепции и принципы, подобные этим, принцип «Сплоченности», который является одним из пересечений почти всех концепций и принципов, остается позади. . Постараюсь подробнее остановиться на принципе «сплоченности».

Принципы кодирования

Попробуем запомнить некоторые принципы кодирования и связать их с темой «сложности»:

- Делайте это просто, глупо
- Пишите СУХОЙ код
- Разделение ответственности
- Вам это не понадобится
- Документируйте свой код
- Принципы SOLID

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

KISS: Следует избегать ненужной сложности

СУХОЙ: избегает дублирования знаний

Разделение проблем: инструктирует избегать написания длинных сложных функций.

YAGNI: избегает переделок и снижает сложность

К чему может привести «сложность»?

По сути, Сложность может привести к тому, что вы «заблудитесь» в любом путешествии.

Тесно связанная кодовая база
Работает, но неудобна в сопровождении строк кода, ограниченная гибкость (или отсутствие гибкости) кода. Слишком большая зависимость между функциями/модулями, и это также ведет в тупик.

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

Плохая удобочитаемость
Нечеткие указания, дублированные бизнес-правила, умноженная/дублированная бизнес-логика, время от времени можно услышать «это доступно в документации, но работает по-другому в приложении», непоследовательное поведение, основанное на прочитанном.

Что такое сплоченность и сцепление? Почему важна «высокая сплоченность, низкая связанность»?

Сплоченность — это мера степени, в которой элементы модуля/компонента функционально связаны. Это степень, в которой все элементы, направленные на выполнение одной задачи, содержатся в модуле/компоненте.

Связь — это мера степени взаимозависимости между компонентами/модулями. У хорошего программного обеспечения низкая связанность.

Наилучший сценарий:

Высокая сплоченность

Высокая связность — это концепция разработки программного обеспечения, которая выражает, насколько близко все члены или весь код в классе поддерживают основную цель модуля/компонента/функциональности. Можно учесть, что SoC реализован очень сильно. Классы с сильно связанными функциями определяются как имеющие высокий уровень совместимости; эвристическая цель состоит в том, чтобы сделать связность как можно более высокой.

Низкая связь

Модули должны быть максимально независимы от других модулей. Эта взаимозависимость обеспечивает гибкость и не оказывает большого влияния на другие компоненты/модули. Таким образом, Low Coupling был бы лучшим подходом для кодовой базы для обеспечения квалифицированных поставок.

Как мы можем измерить сложность кодирования?

  • Отсутствие архитектуры кодирования не означает «высокой сложности».
  • На первый взгляд непонятная структура папок не означает «Высокую сложность».
  • Отсутствие юнит-тестов или интеграционных тестов не означает «высокой сложности».
  • Сложность следует оценивать в рамках конкретных значений. Это не параметр, который можно оценить для частичного или всего приложения с прогнозированием и предположением.

Цикломатическая сложность

Цикломатическая сложность — измерение сложности исходного кода. Это программная метрика, используемая для обозначения сложности программы. Он вычисляется с использованием графа потока управления программы.

Например, если исходный код не содержит оператора потока управления, тогда его цикломатическая сложность будет равна 1, а исходный код содержит один путь. Точно так же, если исходный код содержит одно условие if, тогда цикломатическая сложность будет равна 2, потому что будет два пути: один для истинного, а другой для ложного.

И с этим способом измерения уже есть некоторые методы расчета внутри функций и некоторые характеристики:

M = E-N+2P

E = количество ребер в графе потока управления
N = количество узлов в графе потока управления
P = количество связанных компонентов

С другой стороны, есть инструменты для измерения этого или близкого к этому, такие как Visual Studio Calculate Code Metrics, VS Code CodeMetrics (не совсем алгоритм CC, но очень близкий к этому алгоритму) и т. д.

Категоризация для интерпретации цикломатической сложности

В этой презентации Том МакКейб вводит следующую классификацию для интерпретации цикломатической сложности:

  • От 1 до 10: простая процедура: небольшой риск
  • Между 11 и 20 Более сложные: умеренный риск
  • От 21 до 50 Комплекс: высокий риск
  • 50 и выше: непроверяемый код: очень высокий риск

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

Пример списка предложений по снижению цикломатической сложности:

Заключение

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

Ваше здоровье!