На прошлой неделе я получил вопрос, на который я ответил очень кратко, но я чувствовал, что для его полного ответа потребуется сообщение в блоге. Итак, вот сообщение в блоге.
Должен ли автор кода нести ответственность за нечто большее, чем просто модульное тестирование, или рецензирование имеет смысл?
Загруженный вопрос, верно? Очевидно, парень, задающий этот вопрос, считает, что автору следует как провести модульное тестирование, так и провести рецензирование. И я согласен. Но ограничивать роль программиста даже этими двумя вещами — очень узкое представление о программировании.
Затем я задумался об этом и понял, что большая часть того, что мы будем пытаться выполнить с помощью анализа кода, включает в себя все, что мы хотели бы включить в список того, за что отвечает разработчик. Кроме того, проверка кода — это, в основном, проверка, гарантирующая, что 1) код выполняет то, что должен, и 2) код легко поддерживать в будущем.
Другими словами, все, что включает в себя слово «рецензирование» или «рецензирование кода», в основном касается ясности кода.
Понятность кода решает проблему, с которой мы все сталкиваемся, когда подбираем новый фрагмент кода. Вы можете это легко понять? Я только что прослушал эпизод DotNetRocks, который был посвящен тому факту, что мы проводим большую часть нашего времени за чтением кода, и все же никто не говорит о том, как мы могли бы сделать это лучше. Один из способов, с помощью которого мы можем лучше читать код, — это написать его более четко.
Вот 15 способов облегчить чтение кода:
Сделайте ваш код красивым
Я помню, когда я занимался программированием в Clipper, у нас был один парень, который всегда показывал код, готовый к печати в учебнике. Я имею в виду, независимо от того, что вы должны были сказать о том, что он на самом деле кодировал, визуальное представление кода было делом прекрасным. Он заставил нас поверить, что весь его код выглядел так. Затем он пошел работать в какую-то другую компанию, и мы фактически посмотрели другой код, который он написал. Это выглядело как любой другой код.
Но это преподало мне урок. Урок, который мне, к сожалению, еще нужно вспомнить. Красивый код проще в обслуживании и много говорит о качестве кода. Точно так же, как вы не пошли бы на собеседование без костюма, потому что то, как вы одеваетесь, подразумевает что-то о том, как вы будете программировать, ваш код должен подразумевать качество тем, как оно выглядит, прежде чем вы начнете его читать.
Установите и соблюдайте соглашения по присвоению имен для вашего кода
Я писал об этом раньше. В частности, когда впервые появилась .NET в статье о венгерской нотации . Как я отмечаю в этой статье, отсутствие венгерской нотации не означает, что у вас нет стандартов. Конечно, вы не хотите ставить перед всеми вашими целыми числами нижний регистр «I», потому что вам все равно, какое это число. Но полезно поставить перед кнопкой кнопку с префиксом, чтобы ее было проще найти в Intellisense, или, если вам нужно найти в коде то, что вы назвали, гораздо проще найти все кнопки в вашем коде. сюда.
Но есть еще одна причина для создания и соблюдения соглашений об именах. После того, как вы это сделаете, каждому, кто использует эти общие соглашения, будет проще читать ваш код.
Например, там, где я работаю, у нас есть очень странное соглашение об именах. Все наши классы POCO (мы генерируем это сами, потому что мы используем DB2) все UPPERCASE_UNDERSCORE_SEPARATED. И все наши свойства коллекций POCO называются UPPERCASE_UNDERSCORE_SEPARATEDs. Раньше это сводило меня с ума, в основном потому, что я религиозно использую ReSharper и правила по умолчанию не настроены для обработки этого странного соглашения. Но это стандарт, и, я могу вам сказать, вы открываете файл, который использует POCO, и вы знаете, что имеете дело с POCO. Нет вопросов об этом!
Хотя я до сих пор не рекомендую эту практику, я привожу вам этот пример, потому что он показывает, насколько стандарт кодирования может мгновенно рассказать вам кое-что о коде, над которым вы работаете, еще до того, как вы начнете читать код.
Создать и соблюдать общую архитектуру
Одна из самых больших проблем, с которыми я сталкиваюсь при чтении кода других людей, заключается в том, что я не могу понять, почему они помещают вещи туда, куда они их кладут. Но наличие общей архитектуры, которую легко объяснить, помогает решить большую часть этой проблемы. Одна из причин, по которой мне нравится работать с фреймворками, заключается в том, что большую часть времени эти решения уже приняты за вас. Например, наличие простой трехуровневой архитектуры, которая разделяет представление, бизнес-правила и доступ к данным на разные части кода, может значительно облегчить чтение кода. В рамках этой базовой структуры вы можете накладывать слои в Model View Presenter, Model View Controller или любых других шаблонах проектирования. Следуйте мантре «Место для всего и все на своем месте», и ваш код будет намного легче следовать.
Называйте объекты как существительные, методы как глаголы
Это настолько просто, что я почти чувствую, что должен написать это здесь. Но я все еще вижу, что принцип нарушает все время. Итак, вот оно. Очевидно, что если вы не следуете объектно-ориентированной методологии. Скажем, вы занимаетесь функциональным или процедурным программированием, вам нужно адаптировать это правило к вашей среде. Но для ООП, ребята и девочки. Хватит нарушать это правило. Это признак незрелости.
Имя Переменная Что они
Точно так же остановитесь на коротких именах переменных, если только вы не используете язык, который все еще настолько архаичен, что требует его. Я писал об этом раньше. Дважды на самом деле. С рантами об использовании i, j и k в качестве имен переменных . Дело в том, что вы хотите иметь возможность читать ваш код и делать это, чтобы ваш код что-то говорил вам о том, что вы делаете. Короткие имена переменных почти всегда не помогают читаемости кода.
Не включайте существительное в ваш метод
Это отличается от того, чтобы просто сказать, что метод должен быть глаголом. Во многих местах я видел код с глаголом И существительным в качестве имени метода. Если у вас есть метод с существительным и глаголом, ваш класс, вероятно, пытается сделать слишком много.
Разве это не выглядело бы смешно, если бы у вас был класс Person, в котором был метод FirstNameToLower ()?
Установите порог цикломатической сложности для ваших методов и соблюдайте их религиозно
Цикломатическая сложность учитывает, сколько операторов должно быть выполнено и, что наиболее важно, сколько условных выражений должно быть выполнено в вашем коде. Самый простой способ уменьшить цикломатическую сложность — это уменьшить количество условий. Но кроме этого, вы можете сделать свой код намного более читабельным, исключив вложение, где это возможно.
Один из моих любимых — вместо написания кода, который выглядит примерно так:
void SomeMethod()
{
if(x != y)
{
// do stuff here
}
}
Вы можете сделать свой код намного более читабельным, написав его так:
void SomeMethod()
{
if(x == y) return;
// do stuff here
}
Точно так же, вместо вложения, когда это не работает, как, например, с операторами while, которые содержат другие операторы while, почему бы не создать метод для каждого оператора while?
Сделать код «Самодокументируемый»
То есть, если вы чувствуете, что ваш код нуждается в комментарии, вы, вероятно, нарушили одно или несколько других предложений по удобочитаемости. Это не означает, что вы никогда не должны добавлять комментарии, но они не должны заменять читаемый код. Я обычно оставляю комментарии для ПОЧЕМУ я что-то сделал и оставляю ЧТО я сделал в коде.
Не добавляйте комментарии к вещам, которые вы можете сделать, читая код
«Эта следующая строка увеличивает значение loopVar на 1» ни к чему хорошему и может в конечном итоге привести к тому, что в вашем коде будет мусор, что затруднит чтение кода. Почему? Потому что loopVar можно переименовать или удалить, и комментарий может остаться навсегда. Пока мы не получим компиляторы, которые проверяют наши комментарии, а также наш исполняемый код, ссылки на переменные в комментариях, как правило, являются плохой практикой, которую следует избегать.
Является ли код твердым ?
- Единственная ответственность классов.
- Принцип открытия / закрытия.
- Принцип замещения Лискова.
- Принцип разделения интерфейса.
- Инверсия зависимостей.
Тестируется ли код?
Если вы будете следовать всем приведенным выше правилам, код должен легко проверяться. Но это то, что вы должны просмотреть свой код явно.
Сбой кода?
Может ли кто-нибудь написать код, который использует какой-либо конкретный метод, который может привести к сбою метода, сгенерировать исключение или иным образом сделать то, что никогда не предназначалось?
Дубликаты кода
Я не знаю о вас, но я почти уверен, что у меня есть код, который выглядит практически одинаково замусоренным по всей моей кодовой базе. Одна из моих текущих целей — заставить себя создавать новый метод каждый раз, когда я собираюсь скопировать и вставить более трех строк кода.
100% покрытие кода
Предполагая, что у вас есть модульное тестирование, у вас есть 100% покрытие кода для всех методов, у которых показатель цикломатической сложности больше 1? Я говорю о коде, который вы написали. Я уже писал о том, какой код должен быть проверен и какой код не нужно проверять.
Изучите словарный запас вашего языка
John Sonmez wrote a very compelling article in 2013 about what makes code readable. In it he says that just like when we learn to read. Code that is readable by a senior level developer may not be readable by an entry level developer simply because the entry level developer doesn’t have a firm grasp of the language. Like John, I’ve been criticized for using the ternary operator because it is too terse. Not descriptive enough. Un-readable. And I’ve always responded that arguing that the syntax isn’t clear is like arguing that a sentence isn’t clear because it uses a word you aren’t familiar with. The word may actually be the perfect word for what the author is trying to communicate. Your understanding of that word does not make the writing bad. It just means the reader has some more learning to do.
What else have you found makes your code more readable? Leave me a comment below.