[Из песочницы] Академия плохого кода: переводы строк, пробелы и отступы
Привет, Хабр! Представляю вашему вниманию перевод статьи «Dark code-style academy: line breaks, spacing, and indentation» автора zhikin2207
Привет, народ! Позвольте мне продолжить рассказ про нашу академию плохого кода. В этом посте мы раскроем другой путь замедления чтения вашего кода. Следующие приёмы помогут вам уменьшить понимание вашего кода и увеличить шансы на появление в нём багов. Готовы? Давайте начнём.
Переводы строк, пробелы и отступы могут убивать.
Как люди читают книги? Сверху вниз, слева направо (по крайней мере — большинство). Это же происходит, когда разработчики читают код. Одна строка кода должна содержать одну мысль, следовательно, каждая строка должна содержать только одну команду. Если вы хотите смутить других разработчиков, вам лучше нарушить эти принципы. И давайте я покажу вам как это сделать.
Пример №1
Посмотрите на этот кусок кода. Одна идея на одной строке. Код такой чистый, что меня аж тошнит.
return elements
.Where(element => !element.Disabled)
.OrderBy(element => element.UpdatedAt)
.GroupBy(element => element.Type)
.Select(@group => @group.First());
Мы можем объединить все операторы в одну строку, но это было бы слишком просто. В этом случае мозг разработчика поймёт, что здесь что-то не так, и он разобьёт операторы слева направо. Проще простого!
Лучше оставить некоторые операторы на одной строке, а некоторые — разделить. Лучший вариант — это когда разработчик может даже не заметить некоторые операторы, что приведёт к недопониманию и в конечном счёте — к ошибке. Другой вариант — мы будем просто медленно уменьшать его понимание этого кода до тех пор, пока он не закричит «Да что это за фигня»?!
return elements.Where(e => !e.Disabled)
.OrderBy(e => e.UpdatedAt).GroupBy(e => e.Type)
.Select(g => g.First());
Как вам такое? Вы можете добавить немного отступов, тогда другие разработчики будут форматировать ваш код десятилетиями, если им понадобится переименовать переменную elements.
return elements.Where(e => !e.Disabled)
.OrderBy(e => e.UpdatedAt).GroupBy(e => e.Type)
.Select(g => g.First());
Отправьте мне открытку, если этот подход пройдёт код-ревью в вашей команде.
Совет: оставьте пару операторов на одной строке и пару — на отдельных строках.
Пример №2
Абсолютно та же идея здесь. Только такой код вы видите намного чаще.
var result =
(condition1 && condition2) ||
condition3 ||
(condition4 && condition5);
Порядок действий такой же. Разделите строки чтобы запутать читающего насколько это возможно. Поиграйте немного с переводами строк, чтобы добиться лучшего результата.
var result = (condition1 && condition2) || condition3 ||
(condition4 && condition5);
И добавьте немного отступов, чтобы сделать код похожим на нормальный.
var result = (condition1 && condition2) || condition3 ||
(condition4 && condition5);
Помните: вы должны соблюдать баланс между нечитаемостью вашего кода и правдоподобностью вашего стиля.
Совет: играйте с переводами строк для получения лучшего результата.
Пример №3
Что насчёт этого?
if (isValid)
{
_unitOfWork.Save();
return true;
}
else
{
return false;
}
Та же проблема, но — с другой стороны. Здесь лучшим вариантом будет объединить операторы в одну строку, конечно, расставив фигурные скобки.
if (isValid) { _unitOfWork.Save(); return true; } else { return false; }
Этот подход будет работать только в случае, если у вас немного операторов в блоках «то» и «иначе». В противном случае ваш код может быть отклонён на этапе код-ревью.
Совет: объединяйте маленькие if/for/foreach операторы в одну строку.
Пример №4
80 символов в строке — это рекомендуемый стандарт на текущий момент. Это позволяет вам держать концентрацию разработчика, когда он читает ваш код. Более того, вы можете открыть два документа одновременно на одном экране когда это нужно, и у вас останется место для обозревателя решений.
bool IsProductValid(
ComplexProduct complexProduct,
bool hasAllRequiredElements,
ValidationSettings validationSettings)
{
// code
}
Проще всего замедлить чтение вашего кода, заставив других разработчиков скроллить ваш код горизонтально. Просто игнорируйте правило 80 символов.
bool IsProductValid(ComplexProduct complexProduct, bool hasAllRequiredElements, ValidationSettings validationSettings)
{
// code
}
Это супер просто: забыть, что было до того, как вы начали скроллить, или пропустить строку, на которой вы начали. Отличный трюк.
Совет: нарочно игнорируйте правило 80 символов.
Пример №5
Пустая строка в правильном месте — это сильный инструмент для группировки вашего кода и ускорения его чтения.
ValidateAndThrow(product);
product.UpdatedBy = _currentUser;
product.UpdatedAt = DateTime.UtcNow;
product.DisplayStatus = DisplayStatus.New;
_unitOfWork.Products.Add(product);
_unitOfWork.Save();
return product.Key;
Пустая строка в неправильном месте в сочетании с другими советами этой статьи может помочь вам сохранить вашу работу. Какую пустую строку вы предпочитаете?
ValidateAndThrow(product);
product.UpdatedBy = _currentUser;
product.UpdatedAt = DateTime.UtcNow;
product.DisplayStatus = DisplayStatus.New;
_unitOfWork.Products.Add(product);
_unitOfWork.Save();
return product.Key;
Совет: вставляйте пустые строки рандомно.
Пример №6
Когда вы делаете коммит в репозиторий, у вас есть крошечная возможность посмотреть, что именно вы собираетесь коммитить. НЕ ДЕЛАЙТЕ ЭТОГО! Это нормально, если вы добавили лишнюю пустую строку как здесь.
private Product Get(string key)
{
// code
}
private void Save(Product product)
{
// code
}
Или, что еще лучше, — добавили несколько пробелов на пустой строке (чтобы понять разницу, выделите 5ю строку).
private Product Get(string key)
{
// code
}
private void Save(Product product)
{
// code
}
Зачем вам это нужно? Код продолжает работать (но это не точно). Вы продолжаете понимать ваш код, но другой разработчик будет понимать ваш код меньше. Вы не можете просто добавить несколько лишних пробелов в общие методы сразу (код-ревью — наш враг), но использование этой практики создаст беспорядок уже через пару недель активной разработки.
Ещё одна дополнительная выгода при использовании лишних пробелов в строке появляется тогда, когда другие разработчики коммитят связанную функциональность, их IDE может автоматически исправлять форматирование. На код-ревью они увидят тысячу красных и зелёных строк. Если вы понимаете о чём я ;)
По этой же причине вы можете настроить табы в вашей IDE, если вы используете пробелы в вашем проекте, и наоборот.
Совет: не смотрите на код перед коммитом.
Пример №7
Обходите тех разработчиков, которые могут увидеть лишние пробелы в коде. Они опасны для вашей карьеры.
product.Name = model.Name;
product.Price = model.Price;
product.Count = model.Count;
Совет: знай своего врага.
Трудная работа — сделать свой код неподдерживаемым. Когда вы копите много мелких проблем, они растут без вашего участия. Молодые разработчики будут писать свой код по вашим шаблонам. В один прекрасный день в течение код-ревью вы услышите «Что за фигня?» от вашего тимлида, и тут вы получите возможность использовать коронную фразу: «Что? Мы всегда так делаем», и покажете ему тысячу мест в коде, где написано так же.
Развлекайтесь.