Кратко рассмотрим 12 признаков, когда код можно улучшить:
1. Duplicated Code — иногда повторяющийся код не всегда несет в себе пользу. Выделяют как ярко выраженные повторы, так и слабо выраженные. Примером явного повтора может являться копирование одинаковых строчек кода, в то же время повторение может проявляться в структурах или шагах обработки, которые внешне различны, но, несмотря на это, одинаковы по своей сути (слабо выраженный). В своем коде лучше избегать таких повторов и если есть возможность объединять их.
2. Long Method — короткие методы лучше длинных. Основная причина того, что короткие методы предпочтительнее, связана с распределением логики. Два длинных метода легко могут содержать повторяющийся код. Всего лишь разбив эти методы на более мелкие, можно найти для них способы совместно использовать единую логику. Оптимальным количеством строк для простого метода является 10 строк.
3. Conditional Complexity — в сложной архитектуре условная логика плоха. Понятно, что условная композиция проста в использовании, но по мере увеличения сложности программы условная логика может дать сбой в ее понимании. Например, вы реализуете несколько новых функциональных возможностей, и ваши условия накапливаются как снежный ком, усложняя понимание кода и увеличивая нагрузку программы на систему.
4. Primitive Obsession — сильная зависимость и зацикленность на простых типах данных (string, integer, float, list, array и т.д). Вместо того, чтобы использовать примитивные типы данных, лучше использовать классы, так как они могут быть настолько подстроены под конкретные цели, насколько это необходимо. Во многих случаях классы предоставляют более простой и естественный способ моделирования сущностей, чем примитивы. Кроме того, как только класс создан, часто обнаруживается, что и другой код системы относится к этому же классу. Зацикленность на примитивах может происходить в случаях, когда еще не видно, как абстракция более высокого уровня может прояснить и упростить код.
5. Indecent Exposure — методы и классы видимы тогда, когда они должны быть сокрыты. Такая проблема возникает, когда методы или классы, которые должны быть невидимыми для клиентов, видны им. Они открыты, и клиент знает о коде, который неважен или важен только косвенно. Разумеется, это усложняет проект и порой может угрожать ее надежности.
6. Solution Sprawl — "расплывшееся решение". Такая ситуация возникает когда код и/или данные, реализующие ответственность, расползаются по многочисленным классам. Причиной "расползающегося решения" может быть быстро увеличивающаяся функциональная возможность (например, добавление новых функций в приложение) проекта. Часто не выделяется достаточно времени для того, чтобы упростить и объединить проект, в связи с чем возникают такие проблемы.
7. Alternative Classes with Different Interfaces — интерфейсы двух классов различны, а классы все еще достаточно похожи. Если между двумя классами можно обнаружить сходство, то можно сделать так, чтобы классы использовали общий интерфейс. Но иногда нельзя непосредственно изменять интерфейс класса (например: работа с библиотекой стороннего производителя).
8. Lazy Class — неоптимальность класса. Классы, которые не окупают себя или, например, их можно объединить с другими классами, оптимальнее ликвидировать.
Large Class — класс, "берущий на себя много". Другой крайностью класса может быть то, что в классе реализовано множество функциональных возможностей программы. В таком случае лучше один функционал программы реализовать в отдельном классе. Так вы не запутаетесь в вашем коде, и оптимизировать его будет проще.
9. Large Class — класс, "берущий на себя много". Другой крайностью класса может быть то, что в классе реализовано множество функциональных возможностей программы. В таком случае лучше один функционал программы реализовать в отдельном классе. Так вы не запутаетесь в вашем коде, и оптимизировать его будет проще.
10. Switch Statements — многочисленное количество условных операторов. Условные операторы иногда просто необходимыми, но они становятся лишними тогда, когда они делают проект более запутанным и/или менее гибким, чем это необходимо. В таком случае лучше всего заменять такие операторы выбора вариантов на более объектно-ориентированные или полиморфные решения.
11. Combinatorial Explosion — многочисленные фрагменты кода, дублирующие одно и то же действие, но с использованием различных объектов и данных. Признак Combinatorial Explosion можно назвать тонкой формой дублирования. Он существует тогда, когда, например, множество методов выполняют аналогичные действия с разными данными. Конкретный пример: в классе есть множество методов для выполнения запросов. Каждый из этих методов выполняет запрос, используя особые условия и данные. Чем больше специализированных запросов необходимо поддерживать, тем больше методов для запросов придется создать. В конце концов, очень быстро произойдет взрывное увеличение числа методов, управляющих множеством способов выполнения запросов.
12. Oddball Solution — разные способы решения одной и той же проблемы в одной системе. Такая проблема возникает когда какая-либо задача решается одним способом и тут же решается другим способом в этой же системе, но часто одно из решений является неустойчивым. Чтобы решить, что оставлять, стоит сначала определить предпочтительное решение. В некоторых случаях предпочтительным может оказаться менее используемое решение, если оно лучше решения, применявшегося большую часть времени.