Введение
Я делюсь своими заметками о «сложности» — концепции, с которой мы часто сталкиваемся при разработке приложений и продуктов.
Принципы 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.
- Перестаньте быть милым в откладывании дел
- Направляйте невыполненную работу для рефакторинга соответствующих элементов с соответствующим тегом, например для снижения сложности.
- С вашей точки зрения, если какой-либо принцип усложняет решение/функцию/модуль или приложение в целом, проведите мозговой штурм с вашей командой.
- Запуск новой функции в короткие сроки не означает создание плохого кода.
Ваше здоровье!