Как найти ненужные части вашего кода [Часть XLVII]
28 декабря 2023 г.Ваш код неприятен, потому что, вероятно, существует множество случаев, когда его можно было бы отредактировать или улучшить.
Большинство этих запахов — всего лишь намеки на что-то неладное. Следовательно, их не обязательно исправлять как таковые… (Хотя вам стоит над этим разобраться.)
Запах предыдущего кода
Вы можете найти все предыдущие запахи кода (Часть I – XLVI) здесь.
Продолжим...
Код Smell 231 – избыточные данные
Где ваши источники истины?
<блок-цитата>TL;DR: скажите это только один раз
Проблемы
- Нарушение принципа «Не повторяйся».
- Проблемы с согласованностью
- Удобство обслуживания
- Тестирование и отладка
Решения
- Сохраняйте ответственность за соответствующие объекты и делегируйте их единому источнику достоверной информации. ол>
- [x] Руководство
- При проблемах с производительностью вы можете добавить кеши< /a> и избыточность, но вам потребуются дополнительные усилия для синхронизации данных.
- Данные
- Нарушение принципа DRY.
- Удобство обслуживания
- Эффект пульсации
- Создайте повторяющийся код
- Введите абстракцию
- Замените ссылки и укажите новую абстракцию.
- Удалить дублирование ол>
- [x] Полуавтоматический
- Раздутие
- Неправильное название
- Точно опишите свои коллекции. ол>
- [x] Полуавтоматический
- Имена
- Низкая производительность
- Отсортируйте условия от более быстрого к более медленному. ол>
- [x] Полуавтоматический
- Производительность
- Соединение
- Тестируемость
- Повторное использование
- Композиция функций
- Разъедините код и избегайте побочных эффектов.
- Внедрить место назначения вывода ол>
Контекст
Принцип «Не повторяйся» (DRY) призывает вас избегать избыточности и дублирования поведения.
Избыточные данные могут привести к несогласованности, поскольку обновления или изменения необходимо вносить в нескольких местах.
Если вы обновите один экземпляр данных и забудете обновить другой, ваша система может стать нестабильной, что может привести к ошибкам и неожиданному поведению.
Поддержание избыточных данных может стать кошмаром, когда дело доходит до внесения изменений или обновлений, поскольку это увеличивает рабочую нагрузку и вероятность возникновения ошибок во время обслуживания.
Благодаря единому источнику достоверной информации вам нужно вносить изменения только в одном месте, что упрощает процесс обслуживания.
Когда данные повторяются в нескольких местах, становится сложно определить авторитетный источник этих данных, что приводит к путанице для разработчиков.
Пример кода
Неверно
class Transfer:
def __init__(self, amount, income, expense):
self.amount = amount
self.income = income
self.expense = expense
class Income:
def __init__(self, amount):
self.amount = amount
# amount is the same for party and counterparty
class Expense:
def __init__(self, amount):
self.amount = amount
transfer_amount = 1000
# simplification: should be a money object with the currency
income = Income(transfer_amount)
expense = Expense(transfer_amount)
transfer = Transfer(transfer_amount, income, expense)
print("Transfer amount:", transfer.amount)
print("Income amount:", transfer.income.amount)
print("Expense amount:", transfer.expense.amount)
Верно
class Transfer:
def __init__(self, amount):
self.amount = amount
self.income = Income(self)
self.expense = Expense(self)
class Income:
def __init__(self, transfer):
self.transfer = transfer
def get_amount(self):
return self.transfer.amount
class Expense:
def __init__(self, transfer):
self.transfer = transfer
def get_amount(self):
return self.transfer.amount
transfer_amount = 1000
transfer = Transfer(transfer_amount)
print("Transfer amount:", transfer.amount)
print("Income amount:", transfer.income.get_amount())
print("Expense amount:", transfer.expense.get_amount())
Обнаружение
Это смысловой запах
Исключения
Теги
Заключение
В более крупных и сложных системах избыточность становится серьезной проблемой.
По мере роста вашей системы проблемы, связанные с обслуживанием и синхронизацией избыточных данных, также возрастают.
Избыточные данные также увеличивают площадь поверхности для тестирования и отладки.
Вам необходимо убедиться, что все копии данных работают согласованно, а это может оказаться непростой задачей.
Отношения
Отказ от ответственности
Запахи кода — это мои мнение.
Кредиты
Фото Йоргена Холанда на Unsplash
<блок-цитата>
Все в конечном итоге потерпит неудачу. Аппаратное обеспечение подвержено ошибкам, поэтому мы добавляем резервирование. Это позволяет нам пережить отдельные сбои оборудования, но увеличивает вероятность возникновения хотя бы одного сбоя в любой момент времени.
Майкл Найгард
https://hackernoon.com/400- Thought-provoking-software-engineering -quotes?embedable=true
Код Smell 232 – многоразовый код
Не повторяйтесь. Не повторяйтесь
<блок-цитата>TL;DR: недостающие абстракции можно найти, просматривая повторяющийся код
Проблемы
Решения
Контекст
Повторяющийся код — признак отсутствия абстракций.
Это естественно в процессе обучения, поскольку мы не можем предвидеть эти абстракции.
Пример кода
Неверно
def calculate_area(length, width):
return length * width
def calculate_volume(length, width, height):
return length * width * height
Верно
def calculate_area(length, width):
return length * width
def calculate_volume(length, width, height):
base_area = calculate_area(length, width)
return base_area * height
Обнаружение
Некоторые линтеры могут находить повторяющиеся шаблоны кода.
Исключения
Абстракция должна иметь соответствие зависимости от биекции
Теги
Заключение
Повторяющийся код — это проблема и намек на недостающую абстракцию.
Помните, что вам не нужно избегать копирования и вставки.
Вы должны явно написать повторяющийся код и удалить дублирование, введя абстракцию.
Отказ от вырезания и вставки – это ярлык и признак преждевременной оптимизации.
Отношения
Code Smell 46 – повторяющийся код
Code Smell 182 – чрезмерное обобщение< /п>
Кредиты
Фото Митчелла Гриста на сайте Unsplash
<блок-цитата>
Вставка кода из Интернета в рабочий код похожа на жевательную резинку, найденную на улице.
Майк Джонсон
Код Smell 233 — количество коллекций
Вы считаете коллекции или Collections.count?
<блок-цитата>TL;DR: выбирайте узкие имена
Проблемы
Решения
Контекст
Имена имеют большое значение и не должны вводить читателя в заблуждение. f Вы даете имена вещам и теряете объем имени.
Важно точно определить ожидаемую ссылку на имена.
Пример кода
Неверно
const standardModelParticles = {
quarks: [
{
name: "Up",
charge: "2/3",
type: "Quark",
},
{
name: "Down",
charge: "-1/3",
type: "Quark",
},
// ...
],
leptons: [
{
name: "Electron",
charge: "-1",
type: "Lepton",
},
{
name: "Muon",
charge: "-1",
type: "Lepton",
},
// ...
],
gaugeBosons: [
{
name: "Photon",
charge: "0",
type: "Boson",
},
{
name: "W Boson",
charge: "±1",
type: "Boson",
},
// ...
],
higgsBoson: [
{
name: "Higgs Boson",
charge: "0",
type: "Scalar Boson",
},
],
};
const quarks = standardModelParticles.quarks.length;
// Bad name. It does not represent a count
// But a Collection of things
Верно
const standardModelParticles = {
}; // Same as the "Wrong" example
const quarksCount = standardModelParticles.quarks.length;
Обнаружение
Некоторые линтеры могут проверять типы и имена и делать вывод об ошибке
Теги
Заключение
Берегите свои имена.
Используйте инструменты автоматического рефакторинга всякий раз, когда сталкиваетесь с плохой репутацией.
Отношения
Код Smell 163 — Коллекция по имени
Code Smell 134 – Специализированные бизнес-коллекции
Кредиты
Фото Сэнди Миллар на Unsplash
<блок-цитата>
Некоторые люди являются хорошими программистами, потому что они могут обрабатывать гораздо больше деталей, чем большинство людей. Но по этой причине выбор программистов имеет множество недостатков: это может привести к созданию программ, которые никто другой не сможет поддерживать.
Батлер Лэмпсон
Код Smell 234 – Длинная цепь
Будьте умны (и ленивы) в условиях низкой производительности
<блок-цитата>TL;DR: Преждевременная оптимизация — это зло. Оптимизация – это хорошо.
Проблемы
Решения
Контекст
Читабельность всегда важна, поэтому следует избегать преждевременной оптимизации.
Непреждевременная оптимизация происходит, когда у вас есть реальные доказательства того, что вы можете улучшить время выполнения кода без особых проблем с читабельностью.
Пример кода
Неверно
def is_warm():
# This is a fast api call to your thermometer
response = requests.get
("https://iot-device-api.example.com/current_temperature")
temperature_data = response.json()
return temperature_data.get('temperature', 0) > 25
def is_weekend():
# This function checks if today is a weekend
# based on a slow calendar API call
response = requests.get
("https://calendar-api.example.com/today")
calendar_data = response.json()
return calendar_data.get('day_of_week', '').lower()
in ['saturday', 'sunday']
def is_sunny():
# Very slow function to a low performant weather API call
response = requests.get
("https://weather-api.example.com/current")
weather_data = response.json()
return weather_data.get('weather', '') == 'sunny'
is_sunny_value = is_sunny()
is_warm_value = is_warm()
is_weekend_value = is_weekend()
if is_sunny_value and is_warm_value and is_weekend_value:
# the 3 conditions are always evaluated
print("Let's go outside!")
else:
print("Stay at home.")
Верно
if is_warm() and is_weekend() and is_sunny():
# the 3 conditions are evaluated in short circuit
# and sorted from fastest to slowest
# for a fast exit
print("Let's go outside!")
else:
print("Stay at home.")
Обнаружение
Вы можете обнаружить медленные вызовы с помощью реальных тестов.
Не учитывайте сложность алгоритма, поскольку иногда она не связана с реальным распределением данных. (например, оптимизация массива из нескольких элементов).
Теги
Заключение
Найдите узкие места, используя правила Парето.
Оптимизируйте критически важные разделы кода.
Отношения
Code Smell 140 – оценка короткого замыкания
Code Smell 145 — Взлом при коротком замыкании
Кредиты
Фото Ника Абрамса на Unsplash
<блок-цитата>
Залогом эффективности является элегантность, а не батальоны особых случаев.
Джон Бентли и Дуглас Макилрой
Код Smell 235 – побочные эффекты консоли
Вы выполняете вычисления и регистрируетесь в одном и том же месте
<блок-цитата>TL;DR: избегайте побочных эффектов
Проблемы
Решения
Контекст
Вывод на консоль внутри внутренней функции приводит к возникновению связи и побочных эффектов
Пример кода
Неверно
https://gist.github.com/mcsee/c8fcd38572bce8e59bf28ceaede7a055?embedable=true р>
Верно
https://gist.github.com/mcsee/1c4881a54286a827b8fc037fdd89722c?embedable=true р>
Обнаружение
[X] Автоматически
Некоторые линтеры предупреждают об этом использовании
Теги
- Глобальные значения
Заключение
Вместо ведения журналов непосредственно во внутренних функциях более модульный и гибкий подход заключается в том, чтобы функции возвращали значения или выдавали исключения при возникновении ошибок.
Вызывающий код затем может решить, как обрабатывать и регистрировать эти результаты в зависимости от стратегии регистрации приложения.
Отношения
[Код Smell 17 — глобальные функции])
Кредиты
Изображение создано Midjourney
<блок-цитата>
Память подобна оргазму. Будет намного лучше, если вам не придется притворяться.
Сеймур Крей
На следующей неделе еще 5 запахов.
Оригинал