Измий още една чиния: просто правило за постоянно чиста codebase

Практична философия за софтуерна разработка, вдъхновена от Boy Scout Rule: винаги оставяй кода по-чист, отколкото си го намерил - измий още една чиния. Защо micro-refactoring има значение и как да го прилагаш, без да проваляш delivery-то.

TL;DR: Отнасяй се към всяка промяна в codebase-а си като към готвене. Ще изцапаш няколко чинии. Когато приключиш, измий не само чиниите, които си използвал - измий още една. С времето този малък излишък от грижа се натрупва в кухня (codebase), която остава чиста, вместо да се разпада в хаос.


Метафората: готвене, чинии и код

Представи си професионална кухня. Всяко приготвено ястие цапа няколко чинии - дори в най-подредената бригада. Сега си представи, че след като завърши ястието си, всеки готвач мие точно чиниите, които е изцапал. Кухнята ще се държи на ръба на приемливата чистота, но ентропията ще пропълзи вътре: малко засъхнала мръсотия тук, оцветена дъска за рязане там. Накрая бъркотията се натрупва.

Сега обърни правилото: след готвене всеки chef мие една чиния повече, отколкото е изцапал. Бавно кухнята става по-чиста от преди - не просто поддържана, а подобрена. Същото важи и за софтуера: всяка задача, която поемаш, трябва да добавя поне малък излишък от чистота към codebase-а - още един тест, по-ясно име, една разделена функция, премахната мъртва dependency. Навикът за "+1 чиния" е начинът една codebase да остава здрава.

Наричам това правилото "Измий още една чиния".

Отзвук от занаята: в добра компания си

Това не е самотна философия. Мислители в софтуера проповядват сходни идеи от десетилетия:

  • "Винаги оставяй лагера по-чист, отколкото си го намерил." Това е класическото Boy Scout Rule, популяризирано в софтуера от Robert C. Martin. Духът е същият: подобрявай по малко, всеки път.
  • Technical debt като метафора (Ward Cunningham): дългът трупа лихва - игнорирай го и утре "кухнята" струва повече за използване. Ако изплащаш част от него в движение, оставаш платежоспособен.
  • Refactoring като малки, постоянни стъпки (Martin Fowler): миниатюрни промени, които запазват поведението, но подобряват дизайна. Малките стъпки означават нисък риск и устойчив momentum.
  • "Make it work, make it right, make it fast" (Kent Beck): първо correctness, после чистота, после performance. Измиването на допълнителната чиния живее във фазата "make it right" - преди да оптимизираш преждевременно.
  • Broken windows theory, приложена към кода (Andrew Hunt & David Thomas): видимата бъркотия кани още бъркотия. Поправянето на един "прозорец", преди да се разпространи, пази квартала (codebase-а).

Тези идеи се подсилват взаимно. Всички казват едно и също: не предавай бъркотията нататък; отдели миг да я направиш по-добра.

Защо допълнителната чиния има значение (дори когато си зает)

1. Ентропията е реална

Оставен без грижа, кодът не стои неутрален. Имената се разместват, pattern-ите се разпадат, абстракциите гният. Ентропията е сила; единствената насрещна сила е постоянното, постепенно подреждане. Твоята +1 чиния е micro-обръщане на ентропията.

2. Дългът се натрупва по-бързо, отколкото мислиш

Цената на промяната расте с всяко "ще го оправим по-късно". "По-късно" рядко идва. Лихвените плащания се проявяват като забавена feature работа, крехки deploy-и и test suite-ове, на които никой не вярва. Измиването на една допълнителна чиния днес сваля лихвата утре.

3. Социалният сигнал

Когато съотборниците видят, че почистваш след себе си (и още малко), нормата се измества. Става достоверно - и очаквано - да оставяш кода по-добър, отколкото си го намерил. Културата следва поведението.

4. Momentum, не перфекционизъм

Това не е оправдание за yak shaving. Не преизграждаш кухнята по време на service. Просто минаваш с гъбата по още една чиния - малко, безопасно и бързо. Това е ключът delivery-то да остане на релси.

Как да практикуваш правилото "Измий още една чиния"

Ето как да вградиш навика, без да derail-неш scope-а или сроковете.

1. Приеми "Micro-Refactoring" като част от Definition of Done

  • Преименувай объркваща променлива.
  • Извади малка функция, за да намалиш cyclomatic complexity.
  • Изтрий мъртъв код или неизползвани imports.
  • Добави липсващ test за bug, който току-що си поправил.
  • Обнови документация или README секция, която те е стреснала за минута.

Критерият: Ако отнема повече от няколко минути, не е чиния - това е цялата съдомиялна. Отложи го. Запиши го като ticket.

2. Използвай Pull Requests като trigger за чистене

Всеки PR може да остави лагера по-чист:

  • Изисквай checkbox или кратка бележка "Какво почисти?".
  • Насърчавай reviewers да искат малки подреждания заедно с review-то си.
  • Отбелязвай PR-ите, които включват този допълнителен polish (shout-out в standup върши чудеса).

3. Автоматизирай лесните чинии

  • Pre-commit hooks за formatting и linting.
  • Static analysis, която маркира complex methods или дълги parameter lists.
  • Dependency checkers за остарели библиотеки.

Остави автоматизираните метли да метат тривиалната бъркотия, за да могат хората да се фокусират върху logic и design.

4. Вгради го в екипните норми

  • Добави правилото към working agreement-а или engineering handbook-а на екипа.
  • Следи micro-refactor wins в retros, ако искаш измеримо доказателство.
  • Понякога pair или mob program, за да разпространиш навика (и смелостта).

5. Знай кога да не миеш

Понякога кухнята гори: production е down, или demo-то е след няколко часа. В emergency, ако трябва, разбий купчината мръсни чинии. Но се върни след кризата. Правилото не е догма; то е дисциплина.

Границата: една чиния, не мивката

Scope creep често се маскира като craftsmanship. Твоята работа е да спреш на "още една чиния". Ако този малък refactor разкрие по-дълбока миризма, запиши я и продължи. Паркирай по-дълбоката поправка:

  • Създай ticket с label refactor: или techdebt:.
  • Свържи го с релевантния code, tests или module.
  • Добави кратка бележка защо има значение.

Направил си дължимото: видял си бъркотията, измил си чиния и си оставил инструкции за останалото.

Пример: да превърнеш messy function във функция, която можеш да тестваш

Before:

function processOrder($order) {
    if(!$order->id) throw new Exception('No ID');
    $tax = 0;
    if ($order->country === 'BG') {
        $tax = $order->total * 0.20;
    } else if ($order->country === 'DE') {
        $tax = $order->total * 0.19;
    }
    // Lots more branching...
    // Sends email, writes to DB, calls payment gateway…
}

Измита чиния:

/**
 * Calculate VAT for an order based on country.
 * Pure function: given (total, country) -> VAT amount.
 */
function vatFor(string $country, float $total): float {
    return match($country) {
        'BG' => $total * 0.20,
        'DE' => $total * 0.19,
        default => 0.0,
    };
}

Сега main function-а ти вика vatFor(), вместо да inline-ва logic. Добавил си micro-test за vatFor(). Това е една допълнителна чиния - просто, ограничено, полезно.

Последни мисли

Още една чиния е нещо малко. Точно това е смисълът. Не ти трябват героични refactor-и, за да държиш codebase здрава; трябва ти култура на малка, постоянна грижа. Превърни го в навик, изплети го в процеса си и след година ще се чудиш защо кухнята ти не е бедствие - защото никога не си я оставил да стане такава.


Call to Action: Следващия път, когато докоснеш файл, попитай се: "Коя допълнителна чиния мога да измия, преди да commit-на тази промяна?" После го направи. Повтори. Промени културата, една безупречна чиния наведнъж.

Източници и допълнително четене


Коментари

Boris D. Teoharov

Автор

Здравей, аз съм Борис

Не съм писател. Не съм философ. Просто съм backend инженер от България, който живее между Laravel опашки и индекси със стотици милиони редове. През останалото време чета медицина, която няма работа да чета, френски романи, които разбирам наполовина, и каквото още малката ми гумена глава реши да дъвче. Две спасени кучета ме държат честен.