Как найти вонючие части вашего кода [Часть XXXIII]

Как найти вонючие части вашего кода [Часть XXXIII]

25 марта 2023 г.

Это пахнет, потому что, вероятно, есть много случаев, когда его можно отредактировать или улучшить.

n Большинство этих запахов являются лишь намеками на то, что что-то может быть не так. Следовательно, их не обязательно исправлять как таковые… (Тем не менее, вы должны изучить это.)

Пахнет предыдущим кодом

Вы можете найти все предыдущие запахи кода (Часть I–XXXII) здесь.

Продолжим...


Code Smell 161 — Абстрактные/конечные/неопределенные классы

Ваши классы являются абстрактными, окончательными или неопределенными

<цитата>

TL;DR: если в вашем языке есть правильный инструмент, ваши классы должны быть либо абстрактными, либо окончательными.

Проблемы

* Классы с всего одним конкретным подклассом

* Нарушение замены Лисков

* Йо-йо Проблема

Решения

  1. Объявите все конечные классы как final, а остальные как абстрактные.

Контекст

Управление иерархиями и композицией — основная задача хорошего разработчика программного обеспечения.

Поддержание работоспособности иерархий имеет решающее значение для обеспечения согласованности и предотвращения дублирования. р>

Пример кода

Неверно

public class Vehicle
{
  // the class is not a leaf. Therefore it should be abstract

  // an abstract method that only declares, but does not define the start 
  // functionality because each vehicle uses a different starting mechanism
  abstract void start();
}

public class Car extends Vehicle
{
  // the class is a leaf. Therefore it should be final
}

public class Motorcycle extends Vehicle
{
  // the class is a leaf. Therefore it should be final
}

Правильно

abstract public class Vehicle
{
  // the class is not a leaf. Therefore it must be abstract  

  //an abstract method that only declares, but does not define the start 
  //functionality because each vehicle uses a different starting mechanism
  abstract void start();
}

final public class Car extends Vehicle
{
  // the class is a leaf. Therefore it is final
}

final public class Motorcycle extends Vehicle
{
  // the class is a leaf. Therefore it is final
}

Обнаружение

  • [x] Автоматически

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

Теги

  • Подкласс

Заключение

Мы должны оглянуться на наши классы и начать квалифицировать их либо как абстрактные, либо как окончательные.

Нет допустимых случаев для двух конкретных классов, один из которых является подклассом другого.

Отношения

Code Smell 11 — Подклассификация повторного использования кода< /а>

Code Smell 136 — Классы только с одним подклассом

Code Smell 37 — Защищенные атрибуты

Code Smell 58 — Проблема йо-йо

Подробнее

Связь — единственная проблема проектирования программного обеспечения

Глубокие подклассы

Отказ от ответственности

Запахи кода — это только мои мнение.

Кредиты

Фото Уильяма Боссена на странице Скрыть


<цитата>

Когда окончательный дизайн кажется слишком простым для объема проделанной вами работы, вы понимаете, что все готово.

Брэйди Кларк


Code Smell 162 — Слишком много скобок

Скобки вводятся бесплатно. Не так ли?

<цитата>

TL;DR: используйте как можно меньше скобок.

Проблемы

  • Читаемость

* Синтаксическая сложность

Решения

  1. Удалите все ненужные скобки.

Контекст

Мы читаем код слева направо (по крайней мере, в западной культуре).

Круглые скобки часто нарушают этот поток, усложняя когнитивные функции.

Пример кода

Неверно

schwarzschild = ((((2 * GRAVITATION_CONSTANT)) * mass) / ((LIGHT_SPEED ** 2)))

Правильно

schwarzschild = (2 * GRAVITATION_CONSTANT * mass) / (LIGHT_SPEED ** 2)

Обнаружение

  • [x] Автоматически

Это полностью автоматизированный анализ кода.

Он основан на синтаксических деревьях.

Его обнаруживают многие инструменты.

Исключения

В некоторых сложных формулах мы можем добавить дополнительные скобки для удобочитаемости терминов.

Теги

  • Читаемость

* Вздутие живота

Отношения

Code Smell 02 — Константы и магические числа< /а>

Заключение

Мы пишем код один раз и читаем его слишком много раз.

Удобочитаемость превыше всего.

Кредиты

Фото Ника Фьюингса на Unsplash


<цитата>

Если кто-то утверждает, что у него идеальный язык программирования, он либо дурак, либо продавец, либо и то, и другое.

Бьерн Страуструп


Code Smell 163 — Коллекция в названии

Вы когда-нибудь видели CustomerCollection?

<цитата>

TL;DR: не используйте слово "коллекция" в своем имени. Это слишком абстрактно для конкретных понятий.

Проблемы

  • Читаемость

* Злоупотребление абстракцией

* Неправильное название

Решения

  1. Переименуйте коллекцию в определенное имя.

Контекст

Именование очень важно.

Нам нужно много работать с коллекциями.

Коллекции прекрасны тем, что им не нужны пустые значения для моделирования отсутствия.

Пустая коллекция полиморфна полной коллекции.

Мы избегаем null и IFs.

Мы часто используем плохие и расплывчатые имена вместо того, чтобы искать хорошие имена в MAPPER.

Пример кода

Неверно

for (var customer in customerCollection) {

    // iterate with current customer

}



for (var currentCustomer in customersCollection) {

    // iterate with current customer

}

Правильно

for (var customer in customers) {

    // iterate with current customer

}

Обнаружение

  • [x] Полуавтоматический

Все линтеры могут обнаруживать такие плохие имена.

Это также может привести к ложным срабатываниям, поэтому мы должны быть осторожны.

Теги

  • Именование

Заключение

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

Точные имена необходимы для понимания нашего кода.

Отношения

Code Smell 134 — Специализированные бизнес-коллекции

Подробнее

Что такое имя - Часть II Реабилитация

Кредиты

Фото Мика Хаупта на Unsplash


<цитата>

Закон Альцгеймера в программировании: смотреть на код, написанный более двух недель назад, все равно что смотреть на код, который видишь впервые.

Дэн Хурвиц


Code Smell 164 — Смешанные отступы

Вкладки и пробелы. Самая серьезная проблема с компьютером.

<цитата>

TL;DR: не смешивайте стили отступов

Проблемы

  • Читаемость

* Согласованность кода

* Нарушение стандартов

Решения

  1. Выберите один из них.

2. Придерживайтесь этого.

3. Добейтесь этого с помощью тестов стандартов кода.

4. Распространите правила для всех кодовых баз.

5. Используйте интегрированную среду разработки, например VSCode или WebStorm, в которой вообще нет вкладок.

Контекст

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

Выбор одного стандарта над другим будет отличным решением.

Пробелы всегда считаются как один.

Вкладки могут насчитывать столько же различных опций.

Пример кода

Неверно

function add(x, y) {

// --->..return x + y;



      return x + y;

}



function main() {

// --->var x = 5,

// --->....y = 7;



    var x = 5,

        y = 7;

}

Правильно

function add(x, y) {

// --->return x + y;

    return x + y;

}

Обнаружение

  • [x] Автоматически

Любой синтаксический анализатор может применять это правило.

Исключения

Некоторые языки, такие как Python, считают отступ частью синтаксиса.

В этих языках отступы не случайны, поскольку изменяют семантику кода.

Теги

  • Стандарты кода

Заключение

На эту тему было так много споров.

Запах связан с их смешиванием, а не с использованием одного вместо другого.

Некоторые IDE автоматически преобразуют одно соглашение в другое.

Отношения

Запах кода 48 — Код без стандартов

Подробнее

<цитата>

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

Тим Бернерс-Ли


Code Smell 165 — Пустые блоки исключений

На первом этапе работы я узнал об ошибке.

<цитата>

TL;DR: не избегайте исключений. Разберитесь с ними.

Проблемы

  • Fail Fast Нарушение принципа

Решения

  1. Перехватить исключение и явно обработать его.

Контекст

В первые дни программирования мы давали привилегию работающим системам перед обработкой ошибок.

Мы эволюционировали.

Пример кода

Неверно

# bad

import logging



def send_email(): 

  print("Sending email") 

  raise ConnectionError("Oops")



try:

  send_email() 

except: 

  # AVOID THIS

pass

Правильно

import logging



logger logging.getLogger(__name___)

try:

  send_email()

except ConnectionError as exc:

  logger.error(f"Cannot send email {exc}")

Обнаружение

  • [x] Автоматически

Многие линтеры предупреждают нас о пустых блоках исключений

Исключения

Если нам нужно пропустить и игнорировать исключение, мы должны явно задокументировать его.

Теги

  • Исключения

Заключение

Подготовьтесь к устранению ошибок.

Даже если вы решите ничего не делать, это решение должно быть ясным.

Отношения

Code Smell 132 — Исключение: попробуйте слишком широко

Подробнее

Быстрая ошибка

Возобновление следующего пакета при ошибке

Кредиты

Фото Джеймса Беста на Unsplash< /p>

Спасибо, @Ян Джакомелли

Твиттер


<цитата>

Оптимизация тормозит эволюцию. Все должно строиться сверху вниз, кроме первого раза. Простота не предшествует сложности, а следует за ней.

Алан Перлис

Великие цитаты о разработке программного обеспечения


Скоро появятся еще 5 запахов кода…


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE