Модуль 37

Типові помилки та антипатерни

Чудовий вибір теми! Це одна з моїх улюблених тем, бо саме тут ми переходимо від "я просто пишу код, щоб працювало" до "я пишу інженерні рішення".

Ось твій урок у стилі CS50, присвячений антипатернам та культурі коду.


🎓 CS50: Типові помилки та Антипатерни (або "Як не вистрелити собі в ногу")

Привіт, друзі! Це CS50, і сьогодні ми поговоримо про дещо особливе. Ми вже вміємо писати код, який працює. Але чи достатньо цього?

1. 🔥 Вступ: Проблема «Брудної Кухні»

Уявіть, що ви працюєте шеф-кухарем у топовому ресторані. Ви готуєте неймовірно смачну страву. Але при цьому ви розкидали ножі по підлозі, переплутали сіль із цукром у банках без наліпок, а брудний посуд склали горокю прямо на плиті.

Ви віддали страву клієнту. Вона смачна. Клієнт задоволений. Але...

Що станеться, коли прийде наступне замовлення? * Ви перечепитесь через ніж. * Ви не знайдете чисту сковорідку. * Ви знову переплутаєте інгредієнти.

У програмуванні це називається Технічний Борг та Антипатерни. Антипатерн — це рішення, яке здається хорошим і швидким зараз, але створює величезні проблеми потім.

Питання до вас: Чи траплялося вам відкрити свій код, написаний тиждень тому, і подумати: "Хто це писав? І що тут взагалі відбувається?"? Якщо так — вітаю, ви вже знайомі з наслідками антипатернів. Сьогодні ми навчимося наводити порядок на нашій "кухні".


2. 🧠 Теоретична база: Зло під масками

Давайте розберемо три найпопулярніші "гріхи" розробника-початківця. Не хвилюйтеся про складні терміни, ми розберемо їхню суть.

1. Магічні числа (Magic Numbers)

Це коли у коді з’являються цифри, взяті нізвідки. * Як це виглядає: if user_score > 75: ... * Проблема: Чому 75? Це прохідний бал? Це відсотки? Це вік? Якщо через місяць це число зміниться на 80, вам доведеться шукати його по всьому коду. * Як треба: Використовувати константи. PASSING_SCORE = 75.

2. DRY (Don't Repeat Yourself) проти Copy-Paste

Ми всі любимо Ctrl+C, Ctrl+V. Це швидко. * Проблема: Ви скопіювали шматок коду в 5 місць. Потім знайшли помилку. Тепер вам треба виправити її в 5 місцях. Ви забули про одне? Баг залишився. * Як працює "під капотом": Кожна копія коду збільшує ймовірність помилки експоненціально. * Як треба: Якщо ви бачите однаковий код двічі — винесіть його в функцію.

3. Божественний Об'єкт (God Object / Spaghetti Code)

Це функція або клас, який "знає все" і "робить все". * Аналогія: Це якби у вас вдома був прилад, який одночасно тостер, пральна машина і телевізор. Якщо ламається тостер — ви не можете дивитися новини. * Як треба: Принцип єдиної відповідальності (Single Responsibility). Одна функція — одна дія.


3. 🧪 Приклади: Від жаху до краси

Давайте подивимось на код. Я буду використовувати Python, бо він читається як англійська, але логіка однакова для C, Java чи JS.

Приклад 1: Магія чисел

❌ Як не треба:

# Рахуємо ціну зі знижкою та податком
final_price = price * 0.85 * 1.2

Що ви очікуєте? Це спрацює. Але що таке 0.85? А 1.2? Знижка? Податок? Націнка?

✅ Як треба:

TAX_RATE = 1.20       # 20% ПДВ
DISCOUNT_RATE = 0.85  # 15% знижка

final_price = price * DISCOUNT_RATE * TAX_RATE

Чому це краще? Код документує сам себе. Якщо податок зміниться, ми змінимо його в одному місці зверху.


Приклад 2: "Божественна функція"

Уявіть реєстрацію користувача.

❌ Як не треба:

def register_user(username, password):
    # 1. Перевірка валідності (10 рядків коду)
    if len(password) < 8:
        print("Error")
        return
    # ... тут ще куча перевірок ...

    # 2. Збереження в базу даних (5 рядків коду)
    database.save(username, password)

    # 3. Відправка вітального email (ще 10 рядків)
    email.send("Welcome!", to=username)

Що тут поганого? Якщо ви захочете змінити логіку перевірки пароля, ви ризикуєте зламати відправку пошти. Ця функція занадто велика.

✅ Як треба:

def register_user(username, password):
    if not is_valid(password):
        return error("Invalid password")

    save_to_db(username, password)
    send_welcome_email(username)

# Кожна з цих функцій (is_valid, save_to_db...) описується окремо.

Це як конструктор LEGO. Ми будуємо складне з простих, маленьких цеглинок.


4. 🛠 Практична частина

Час закачати рукави!

Завдання 1. Полювання на магію У вас є код: time_in_seconds = days * 86400. Виправте його, використовуючи іменовану константу. Як ви назвете цю константу?

Завдання 2. Рефакторинг (DRY) У вас є такий код:

print("Привіт, Олексій!")
print("Твій баланс: 100 грн")
print("Дякуємо, що ви з нами.")

print("Привіт, Марія!")
print("Твій баланс: 250 грн")
print("Дякуємо, що ви з нами.")

Створіть функцію print_user_info(name, balance), щоб прибрати дублювання.

Завдання 3. Міні-кейс Ви пишете програму для кавомашини. У вас є одна велика функція make_coffee(), яка: 1. Перевіряє наявність води. 2. Гріє воду. 3. Меле зерна. 4. Наливає каву. Розбийте її (на папері або в голові) на 3–4 менші функції. Як би ви їх назвали?

Завдання 4. "А що, якщо..." Уявіть, що ви не використали константу для податку (20%) і прописали * 1.2 у 50 файлах вашої програми. Уряд змінив податок на 22%. Скільки часу ви витратите на виправлення? А скільки, якби це була константа?


5. 💡 Мислення як у розробника

Як відрізнити новачка від профі?

Новачок думає:

"Я напишу це якомога хитріше і коротше, в один рядок, щоб показати, який я розумний. Головне — працює!"

Досвідчений розробник думає:

"Я напишу це так просто і нудно, щоб навіть стажер, який прийде сюди через рік, зрозумів це за 5 секунд. Код читають частіше, ніж пишуть".

Порада від Malan-a: Завжди пишіть код для себе майбутнього. Уявіть, що ви майбутній — це дуже втомлена людина, яка хоче спати, а не розгадувати ребуси вашого коду. Будьте добрими до себе майбутнього.


6. 🧩 Підсумок

Сьогодні ми не вивчили нових команд чи синтаксису. Але ми навчилися дечого важливішого — стилю та гігієни коду.

  1. Магічні числа — зло. Давайте їм імена.
  2. Copy-Paste — ворог. Використовуйте функції.
  3. Великі функції — це хаос. Розділяйте їх на маленькі логічні частини.

Тепер ви вмієте не просто писати код, а проектувати його так, щоб він жив довго і щасливо.

Що далі? Добре, ми написали чистий код. Але як ми можемо бути на 100% впевнені, що він працює правильно в усіх ситуаціях? Невже треба кожен раз запускати й перевіряти вручну? На наступному уроці ми поговоримо про вашу страховку від помилок — Unit-тестування.

Це був CS50. Побачимось! 👋


ℹ️ Як використовувати цей урок?

Ви можете скопіювати цей текст у свій навчальний план або використати як скрипт для відео. Якщо потрібно адаптувати це під конкретну мову (C++, JS, SQL) або додати специфічні інструменти (Linters, SonarQube) — просто скажіть!