← Назад к вопросам

Зачем нужна читаемость кода?

1.2 Junior🔥 131 комментариев
#Soft Skills

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Зачем нужна читаемость кода

Читаемость кода — это одна из самых критичных характеристик в разработке, но её часто недооценивают. Разберу, почему это действительно важно с точки зрения опытного разработчика.

Суть проблемы

Код пишется один раз, а читается много раз. Расчёт простой:

Время написания кода: 8 часов
Время поддержки кода: 8 месяцев = 160 часов

Соотношение чтения к написанию: 20:1

Вывод: время, потраченное на понимание чужого (или своего) кода через месяц, превышает время на его написание в 20 раз.

Реальная стоимость нечитаемого кода

1. Затраты на разработку новых фич

# ❌ Нечитаемый код
def proc_data(d):
    res = []
    for i in range(len(d)):
        if d[i]['st'] > 0:
            a = d[i]['v'] * 1.2
            res.append({'id': d[i]['id'], 'amt': a})
    return sorted(res, key=lambda x: x['amt'], reverse=True)

# Чтобы добавить новую фичу, нужно:
# 1. Потратить 1 час на разбор кода
# 2. Рискнуть сломать существующий функционал
# 3. Написать тесты заново

# ✅ Читаемый код
def apply_markup_and_sort_by_amount(orders: list[dict]) -> list[dict]:
    """
    Применяет 20% наценку на активные заказы и сортирует по сумме.
    """
    marked_up_orders = []
    
    for order in orders:
        if order['status'] > 0:  # активный заказ
            amount_with_markup = order['amount'] * 1.2
            marked_up_orders.append({
                'id': order['id'],
                'amount': amount_with_markup
            })
    
    return sorted(marked_up_orders, key=lambda o: o['amount'], reverse=True)

# Теперь новая фича добавляется легко:
# Просто добавляем фильтр по типу в цикл

Стоимость нечитаемого кода: 1 разработчик × 1 час = 100$ в час = $100 потрачено впустую на разбор.

2. Затраты на баги

# ❌ Нечитаемый код — сложно найти баг
def calc(p, q, r):
    return p * (1 + q) * (1 - r) if q > 0 else p * (1 - r)

# Где баг? Что такое p, q, r? Чему равны магические числа?

# ✅ Читаемый код — баг видно сразу
def calculate_net_price(
    base_price: float,
    tax_rate: float,
    discount_rate: float
) -> float:
    """
    Вычисляет финальную цену с налогом и скидкой.
    Порядок: сначала добавляем налог, потом вычитаем скидку.
    """
    price_with_tax = base_price * (1 + tax_rate)
    price_after_discount = price_with_tax * (1 - discount_rate)
    return price_after_discount

# Явно видно, что скидка применяется ПОСЛЕ налога
# Если это не нужно, баг найдётся за минуту

Стоимость бага в production: 1 баг × 8 часов debug × $100 = $800.

Бизнес-аргументы

1. Скорость разработки

Первые 6 месяцев: нечитаемый код быстрее написать (+20%)
Месяцы 6-12: время удвоится (новые фичи, баги)
Месяцы 12+: разработка встанет на месте

2. Ротация команды

Если разработчик уходит:
- Читаемый код: 1 неделя на адаптацию нового
- Нечитаемый код: 4 недели + риск регрессии

Стоимость: $100/час × 40 часов × 3 новых разработчика = $12,000

3. Техдолг

# Нечитаемый код создаёт техдолг, который растёт экспоненциально
# Месяц 1: 10 строк сложного кода
# Месяц 2: 50 строк (каждая зависит от первых 10)
# Месяц 3: 200 строк (каждая может сломать две предыдущих)
# Месяц 4: Project is unmaintainable

# Читаемый код позволяет масштабировать:
# Месяц 1: 10 строк понятного кода
# Месяц 2: 50 строк (чистая архитектура, легко тестировать)
# Месяц 3: 200 строк (понятная структура)
# Месяц 4: 1000 строк (всё ещё управляемо)

Технические преимущества

1. Меньше багов

# ❌ Нечитаемый — легко сделать ошибку
x = [i for i in l if i.get('a') and int(i.get('c', 0)) > 0]

# Какие баги могут быть?
# - Если 'a' это False, а не None?
# - Если 'c' не парсится в int?
# - Какой порядок логики правильный?

# ✅ Читаемый — очевидны edge cases
active_products_with_stock = [
    product for product in products
    if product.get('is_active', False) 
    and int(product.get('quantity', 0)) > 0
]

2. Легче тестировать

# ❌ Нечитаемый — невозможно тестировать части
def process_user_data(raw_data):
    # 200 строк логики в одной функции
    # Как её тестировать?
    pass

# ✅ Читаемый — каждая функция тестируется отдельно
def validate_user_email(email: str) -> bool:
    """Проверяет корректность email адреса."""
    return '@' in email and '.' in email.split('@')[1]

def parse_user_profile(raw_data: dict) -> UserProfile:
    """Парсит сырые данные в объект пользователя."""
    return UserProfile(...)

def enrich_user_with_metadata(user: User) -> UserWithMetadata:
    """Добавляет метаданные к пользователю."""
    return UserWithMetadata(...)

# Каждая функция тестируется отдельно, просто и чётко

3. Легче рефакторить

# Нечитаемый код: боишься его трогать
# Читаемый код: понимаешь, что произойдёт при изменении

# ✅ Пример
def calculate_discount(
    customer_type: str,
    purchase_amount: float,
    is_member: bool
) -> float:
    base_discount = 0.0
    
    # Скидка по типу клиента
    if customer_type == 'vip':
        base_discount = 0.20
    elif customer_type == 'regular':
        base_discount = 0.10
    
    # Дополнительная скидка для членов
    if is_member and purchase_amount > 100:
        base_discount += 0.05
    
    return base_discount

# Легко добавить:
# - новый тип клиента
# - новое правило скидки
# - логировать решение по скидке

Человеческий фактор

1. Усталость и ошибки

Разработчик устал от нечитаемого кода:
- Снижение внимательности
- Больше опечаток и логических ошибок
- Выгорание и текучка кадров

2. Мотивация команды

Нечитаемый код:
- Разработчики избегают этого модуля
- Никто не хочет это поддерживать
- Зарплата выше для специалистов, готовых работать с ним

Читаемый код:
- Удовольствие от работы
- Гордость за проект
- Лучше удержание кадров

Принципы читаемого кода

1. Дай правильные имена

# ❌
def p(x, y):
    return x + y * 2

# ✅
def calculate_cost_with_tax(base_price: float, tax_rate: float) -> float:
    return base_price + base_price * tax_rate

2. Одна ответственность (Single Responsibility)

# ❌ Функция делает всё
def process_order(order_data):
    # парсит JSON
    # валидирует
    # считает цену
    # отправляет письмо
    # логирует
    pass

# ✅ Каждая функция делает одно
def parse_order(json_data: str) -> Order: ...
def validate_order(order: Order) -> bool: ...
def calculate_order_total(order: Order) -> float: ...
def send_confirmation_email(order: Order) -> None: ...
def log_order_created(order: Order) -> None: ...

3. Короткие функции

# ❌ 150-строчная функция
def complex_business_logic(data):
    # 150 строк

# ✅ Множество маленьких, ясных функций
def handle_payment(payment_data) -> bool:
    return (
        validate_payment(payment_data)
        and process_payment(payment_data)
        and confirm_payment(payment_data)
    )

4. Типизация

# ❌ Не ясно, что это?
def get_user_data(user_id):
    return ...

# ✅ Явно, что ожидается и что вернётся
def get_user_data(user_id: int) -> UserData:
    return ...

Вывод

Читаемость кода критична, потому что:

  1. Экономика: на чтение кода тратится в 20 раз больше времени, чем на его написание
  2. Скорость разработки: новые фичи добавляются медленнее на нечитаемом коде
  3. Надёжность: меньше багов, проще отладка
  4. Масштабируемость: сложнее масштабировать нечитаемый код
  5. Команда: читаемый код мотивирует, нечитаемый приводит к выгоранию

Правило Роберта Мартина:

"Любой может написать код, который понимает компьютер. Хороший программист пишет код, который понимает человек."

Читаемость кода — это не косметика, это фундамент качественной разработки.

Зачем нужна читаемость кода? | PrepBro