handbookНаписать

lessons/001-refactor-to-strategy/step-1/README.md · тема · 4 языка · 39 тестов

Шаг 1: одна функция на все способы доставки ​

Исходный код: switch по способу доставки, внутри if по стране, цены зашиты прямо в ветках.

Урок: От switch к стратегии. Следующий шаг: способы доставки за общим интерфейсом.

Что было ​

Магазин считает доставку на кассе. Покупатель выбирает способ (pickup, courier, post), корзина знает страну, вес и сумму заказа. Всё это попадает в Parcel, а цену возвращает одна функция: ShippingCalculator::cost в PHP, ShippingCost в Go, shipping_cost в Python и shippingCost в TypeScript.

Правила такие:

  • пункт выдачи только по России, 199 рублей, бесплатно от 3000;
  • курьер по России 390 плюс 50 за каждый начатый килограмм, по Беларуси 590 плюс 80;
  • почта по России 290 за любую посылку, за границу 1490 плюс 150 за килограмм;
  • всё остальное - ошибка UnsupportedShipping с текстом "courier is not available for KZ".

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

Что меняем ​

Пока ничего. Это точка отсчёта: код работает, тесты зелёные, и именно эти тесты дальше будут держать рефакторинг. Перед тем как двигать код, нужно зафиксировать поведение, иначе непонятно, что сломалось - устройство или результат.

Тесты описывают правила, а не устройство функции. Таблица из шести посылок проверяет цены: пункт выдачи, бесплатный пункт выдачи от порога, курьер по России и Беларуси, почта по России и за границу. Вторая таблица проверяет отказы: пункта выдачи нет в Беларуси, курьера нет в Казахстане, способа drone нет вообще. На следующих шагах эти таблицы не меняются, меняется только строка, которая создаёт калькулятор.

Как это собирается ​

Собирать нечего: калькулятор не зависит ни от чего и создаётся одной строкой. Корзина просит цену по каждому способу и показывает недоступные как "not available". В списке есть express: маркетинг уже попросил экспресс-доставку по России за 990, но в этом коде её пока нет.

Сценарий целиком с выводом: пример на PHP, он же на Go, Python и TypeScript в панели кода.

Что стало лучше ​

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

Что ещё болит ​

  • Добавить express - значит открыть функцию, которую трогают все, и вставить ещё одну ветку. Тесты на старые способы приходится гонять заново, потому что правка шла в том же месте.
  • Цены, правила по странам и выбор способа перемешаны. Нельзя проверить курьера отдельно от почты: тест всегда идёт через весь switch.
  • Тарифы зашиты в код. Поменять 390 на 420 - это релиз, хотя логика не менялась.
  • Расчёт килограммов делается для всех способов, хотя нужен двум из трёх. Общий код в начале функции - первый признак того, что ветки хотят разойтись.

Запуск: make test T=lessons/001-refactor-to-strategy/step-1

© 2014-2026 Тимур ТурдыевСайт и справочник работают на VPS от AdminVPS