Чому рефакторинг — це постійний процес

Мені здається, що про рефакторинг ми чуємо дуже часто, але кількість питань з цієї теми не зменшується, а навіть збільшується. Тому про нього й розповім на основі власного досвіду.

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

Майже рік тому мене запросили на проєкт тімлідом — зібрати команду і очолити фронт-розробку (оскільки останнім часом я спеціалізуюся на React-застосунках).

Проєкт розробляли майже 10 років. Коли ми сформували команду і почали працювати над ним, то постали перед вибором: або переписувати все з нуля (те, що часто люблять програмісти, але те, що складно зробити у великому застосунку, який уже працює), або робити глибокий рефакторинг.

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

Поганий код вбиває. Хто відповідальний за код і його якість

Важливість якісного коду (який ще називають чистим кодом, clean code за Робертом Мартіном, Uncle Bob) часто пояснюють на прикладі жарту про Джона — «серійного програміста». Суть жарту в тому, що коли програміст робить помилку в програмному забезпеченні, то користувачі витрачають час на те, щоб обійти її. І якщо користувачів дуже багато, то навіть кілька зайвих витрачених хвилин у кожного з них у сумі це сотні років. Також поганий код краде час в інших програмістів.

Але хто ж відповідає за якість коду? Роберт Мартін вважає, що лише програмісти. Одним з прикладів відповідальності він називає доволі свіжу історію з компанією Volkswagen. Великий скандал, який стався через маніпуляції з результатами показів викидів вихлопних газів автомобілів, щоб обдурити тестувальні апарати. На суді СТО компанії, коли його запитали, як це могло статися, відповів, що це зробили кілька розробників з якоїсь причини. Звичайно, ця причина нам зрозуміла — менеджмент попросив про це програмістів. Але вони могли відмовитися виконувати таке завдання. Нині ці спеціалісти в тюрмі (як зазначив Роберт Мартін у своєму виступі), а компанія втратила десятки мільярдів євро.

Що таке рефакторинг і навіщо його виконувати

Рефакторинг (англ. refactoring) — перетворення програмного коду, зміна внутрішньої структури програмного забезпечення для полегшення розуміння коду і внесення подальших змін без зміни зовнішньої поведінки самої системи.

Навіщо той код переписувати? «Щоб робити його кращим» — скаже будь-який програміст. Але кращим для кого? Відповідь проста, але часто не зовсім очевидна — для нас, програмістів. Відомий факт, що код набагато частіше читають, аніж пишуть. Читають код зазвичай програмісти.

Якби розуміння коду спеціалістами не було таким важливим, то не було б потреби в існуванні великої кількості мов програмування. Адже всі мови програмування, що були розроблені і розробляються сьогодні, потрібні саме програмістам, а не комп’ютерам (або процесорам). Бо процесор розуміє лише двійковий код, а спеціалістам для ефективної роботи потрібні більш високорівневі інструменти. І одним з найголовніших аспектів мови програмування є саме її читабельність (наприклад, вважають, що Python завоював свою популярність завдяки тому, що легко читається, тому ця мова підходить новачкам).

Також важливо не забувати, що код, який ми написали, ми самі ж і читаємо. Мій син полюбляє жарти про програмістів. Один з них звучить так: «Хто це такий код написав? О, так це був я...» :) Це до того, що з часом ми забуваємо, що писали й навіщо. І якщо код був не ідеальним, то потім виникають питання до нього.

Технічні аспекти та принципи оцінювання якості коду

Тож якщо якісний код — це код, який легко читати, ми можемо описати деякі характеристики коду, які впливають на його читабельність: іменування змінних, функцій та класів; розмір коду (довжина рядка, розмір класу чи методу); форматування.

Іншою важливою особливістю коду є можливість його розширювати та масштабувати. Наприклад, відомою є проблема, коли клас має багато обов’язків, слабко пов’язаних між собою, що порушує принцип єдиного обов’язку (single responsibility principle). У такому разі краще розділити клас на кілька атомарних елементів.

Деякі аспекти оцінювання якості коду є суперечливими. Тож команда має просто обрати набір стилів та найкращих практик, яких планує дотримуватися. Більшість проблем із якістю ми можемо знайти в коді за допомогою програмного забезпечення, що вже давно існує. Його можна внести в пайплайн CI/CD.

Що таке технічний борг і що з ним робити

Вперше метафору «технічний борг» щодо «брудного» коду запропонував програміст Ворд Каннінг.

Наприклад, якщо ви візьмете кредит у банку, то можете пришвидшити купівлю чогось. Однак повернути вам потрібно буде не тільки основну суму кредиту, а й відсотки, які будуть нараховуватися доти, доки ви повністю не розрахуєтеся з банком.

Також ви можете взяти декілька кредитів одночасно. Ба більше — набрати їх стільки, що сума відсотків переважить ваш сукупний дохід і зробить повне погашення неможливим.

Те саме з кодом. Простий приклад: сьогодні ви тимчасово прискорюєтеся, не написавши тести для нового функціоналу, але тепер це буде потроху сповільнювати прогрес у майбутньому. Доти, доки ви не погасите борг через написання цих тестів.

Піком такої ситуації стає момент, коли ви не можете змінити щось у коді, бо не знаєте, чи щось зламається. З цим ми зіткнулися на проєкті, після чого нам потрібно було спланувати «сплату боргу», який назбирало ціле покоління розробників до нас.

Поширені причини появи технічного боргу (всі вони яскраво проявилися на нашому проєкті, за кожним пунктом можна написати окремий розділ або навіть статтю):

  1. Тиск з боку бізнесу.
  2. Відсутність розуміння наслідків технічного боргу.
  3. Відсутність боротьби з жорсткою обмеженістю компонентів.
  4. Відсутність автотестів.
  5. Відсутність документації.
  6. Відсутність взаємодії між членами команди.
  7. Довготривала одночасна розробка в кількох гілках.
  8. Відкладений рефакторинг.
  9. Відсутність контролю за дотриманням стандартів.
  10. Відсутність компетенції.

Головне, що нам потрібно розуміти, що технічний борг потребує рефакторингу, водночас відкладений рефакторинг збільшує технічний борг. Тому це взаємопов’язані речі.

Чи є причини не робити рефакторинг

Ми вже трохи розібралися, що таке рефакторинг і навіщо він потрібен. Але чи завжди доцільно його робити? Розгляньмо ситуації, коли рефакторинг може нашкодити.

Перечитуючи статтю на «Хабрі» «Цена рефакторинга», мені пригадалася одна ситуація. Коли до нашої команди приєднався Senior-розробник, у пул-реквестах з’явилося багато змін, не пов’язаних з тасками. Понад те, коли він робив код-рев’ю іншим розробникам, то додавав усе більше й більше коментарів на зміну коду (рефакторинг). І начебто це правильно, відповідно до підходу, який описав Роберт Мартін («ми повинні залишати код кращим за той, який отримали»), але щось було не так, щось, що затримувало merge request на дні, а іноді й тижні. І зміни часто починали виходити за межі методів чи класів, які зачіпалися початково. Менеджерам довелося втручатися і пропонувати створювати рефакторинг-таски в беклозі з технічним боргом.

Чому рефакторинг, який має приносити користь, приносив проблеми? Однією з причин була відсутність юніт-тестів, тому рефакторинг часто спричиняв появу нових помилок, а розробники боялися щось змінювати. Тобто юніт-тести — це те, що треба робити передусім. Цим ми і зайнялися, але натрапили на супротив системи з великим технічним боргом — більшу частину коду практично не можна було протестувати (що і було однією з причин, чому розробники, що вже працювали з продуктом, не змогли додати юніт-тести. Як ми виявили пізніше, вони кілька разів намагалися почати писати юніт-тести).

Друга причина полягала в тому, що не було загального розуміння стилів коду та підходів у розробці. Частина команди працювала з кодом багато років, і ці фахівці просто звикли так писати. Перед тим як почати вимагати від людей нової якості коду, потрібно пояснити, які проблеми з цим уже є, як їх краще виправляти. Також запропонували обговорити і затвердити більш докладний DoD (Definition of Done), за яким можна було аргументувати, що не так у коді.

Ну й проблеми в архітектурі. Це дуже важливий момент: розрізняти рефакторинг коду та виправлення (рефакторинг?) архітектури застосунку. Іноді це непросто, тому що вони часто перетинаються, але зазвичай рефакторинг коду не виходить за межі одного модуля і коли ми його проводимо, то робимо код простішим для розуміння. А рефакторимо архітектуру ми здебільшого для полегшення зміни коду в майбутньому.

Чому б не писати код, який не потрібно рефакторити

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

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

Чи справді якісний код потрібен лише програмістам

Поширена думка, що якісний код потрібен лише програмістам (є навіть окремий термін DX — developer experience, або досвід розробника). Але роботи Роберта Мартіна та мій досвід з легасі-системами показують, що якісний код і чиста архітектура (clean architecture) потрібні насамперед самому бізнесу. В книжці Clean Architecture автор описує проєкт зі свого досвіду, в якому збільшення кількості програмістів практично не підвищило продуктивність роботи відділу, а видатки на розробку значно зросли.

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

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

Знаю, що багато хто не погодиться зі схожою думкою, бо бувають ситуації, коли продукт треба зарелізити якнайшвидше, щоб протестувати бізнес-модель, а потім вже братися за покращення коду. Але для того, щоб перевірити бізнес-модель, застосунок не потрібен, можна написати PoC (Proof of Concept), який потім викинути. І це доволі поширена проблема, коли пишуть PoC і після релізу беруть його за основу продукту (адже воно ж працює і вже є багато коду), але то вже інша історія.

Передумови для успішного рефакторингу

Що потрібно мати або треба зробити до початку рефакторингу, щоб зменшити ризики порушення логіки коду? Важливо розуміти, який рівень рефакторингу потрібен — коду чи архітектури. І взагалі, мабуть, спершу варто пересвідчитись у потребі підтримувати код та архітектуру чистими.

Потім треба провести аудит коду та архітектури. Він допомагає виявити поширені проблеми і скласти план робіт. Також можна описати їх і зазначити найкращі практики для уникнення схожих труднощів у майбутньому (навчити команду).

Як я вже писав, важливо мати юніт-тести. Завдяки написанню юніт-тестів можна рефакторити модулі, не хвилюючись про те, що код буде зламано. Під час підготування тесту програміст краще розуміє функціонал, який потрібно протестувати. А ще так можна виявити код, який складно покрити тестами. Це зазвичай є ознакою поганого коду, який потрібно рефакторити. Але тут дилема: ми не можемо рефакторити, поки немає юніт-тестів, але буває, що ми не можемо написати юніт-тести без рефакторингу. Переважно це проблема вищого рівня — в архітектурі. Схожі питання мають вирішувати досвідчені інженери і не в межах «фіксу багу».

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

Ну і, звичайно, потрібна команда, яка зможе це реалізувати. І що дуже важливо — команда має не лише втілити рефакторинг, а й зробити його постійним процесом.

Чи обов’язково задачі на рефакторинг мають бути в беклозі

Чи потрібно додавати задачі на рефакторинг в трекінг-систему, чи його можна проводити в межах наявних задач? Це питання важливе і з погляду того, що часто ми чуємо: «Менеджмент не любить задачі на рефакторинг».

Як на мене, то і так і ні. Є рефакторинг, що має відбуватися завжди, за згаданим принципом американських бойскаутів: «Бачимо сміття — прибираємо». Але якщо виконується маленький баг-фікс і при цьому переписано купа методів та класів, то це ознака, що щось не так з архітектурою. І, найімовірніше, потрібно створити задачу в беклозі на виправлення проблеми.

Існування окремої задачі дає змогу попрацювати над нею більш сконцентровано, а також оцінити вплив змін на роботу застосунку. Уявіть собі здивування тестувальника, який, перевіряючи задачу на зміну тексту на кнопці, помітить, що кнопка тепер має червоний колір, а не зелений (прибрали зайвий клас), або падіння E2E-тестів (видалили зайвий div, за яким орієнтувався тест).

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

Тож рефакторинг — це постійний процес, який має бути невіддільною частиною щоденної роботи програміста. Щоб покращувати код не потрібні окремі тікети, не треба чекати дозволу на це — покращувати код можна (і потрібно) завжди. Але значні зміни (і особливо зміни архітектури системи) краще робити прозоро, тобто в окремих задачах — відповідно до процесу розробки, якого дотримуються на проєкті. Не забуваймо: ми відповідаємо за код, який написали.

👍НравитсяПонравилось15
В избранноеВ избранном3
Подписаться на автора
LinkedIn



Підписуйтесь: Soundcloud | Google Podcast | YouTube


40 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.
Що потрібно мати або треба зробити до початку рефакторингу, щоб зменшити ризики порушення логіки коду? Важливо розуміти, який рівень рефакторингу потрібен — коду чи архітектури. І взагалі, мабуть, спершу варто пересвідчитись у потребі підтримувати код та архітектуру чистими.

А ви впевнені, що зробити рефакторинг архітектури так просто?
У вас були такі приклади в реальності?
Наприклад, переписати React додаток під Angular або навпаки?

Привіт. Абсолютно з вами згоден, рефакторинг це не просто. Що до досвіду — деякий досвід є. Головною метою статті було підняти питання по нашій щоденній роботі, питання про те що рефакторин є невід’ємною складовою нашої роботи, навіть коли ми цього не помічаємо. Дякую вам що не байдужі що цих питань :)

Як я вже писав, важливо мати юніт-тести. Завдяки написанню юніт-тестів можна рефакторити модулі, не хвилюючись про те, що код буде зламано.

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

Все вірно. Піраміда тестування — окрема тема, можливо розробникам також більше про неї треба говорити

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

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

думаю ймовірність в такому випадку невелика, хоча є

А сам процес стає невіддільною частиною роботи з кодом.

Цікаво було б почути, скільки часу ви виділяли на рефакторинг (на тиждень), як до цього ставився до замовник і взагалі скільки часу знадобилося, що закінчити рефакторинг всього проекту.

Різні замовники по різному відносяться. По тому проєкту який в основному згадується в статті — виділялися окремі задачі і на рефакторинг архітектури, і на рефакторинг окремих модулів. Часу витрачається чимало, але не достатньо, все ще попереду :)

Ми вже трохи розібралися, що таке рефакторинг і навіщо він потрібен

Шкода, що в статті не сказано, а ЯК робити рефакторинг (по кроках). Якщо його робити неправильно, то можна отримати ще більше проблем, ніж без нього.

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

Ок, і як же ви робили рефакторинг, коли у вас не було тестів?

Як я згадував у статті — окрема команда покривала апішку автотестами E2E, це дозволило зменшити ризики. Потім деяки частини системи потрібно було переписувати, щоб можна було їх покривати юніт тестами, потім юніт тести, потім решта модулів.

Відсутність контролю за дотриманням стандартів.

Навіть наявність стандартів може призвести до технічного боргу.
Я б сказав — відсутність code review або формальне дотримання

Відсутність компетенції.

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

Компетенцію команди. Впровадили і код рев’ю, і лінтери, і сонар. Що до джуніорів — ви б побачили код написаний принципал інженерами))

Відсутність автотестів.

Відсутність автоматичних тестів безпосередньо не впливає на якість коду. Можна писати ідеальний код і без тестів.

Наверное можно, особенно, если раз написал код и больше он никогда не меняется. В живом проекте такого никогда не наблюдал. И как-бы я ни старался соблюдать OCP, и дорабатывать код исключительно подменой зависимостей, или декораторами или наследованием — все-равно бизнес умудрялся так вывернуть задачу, что все-равно приходилось менять уже написанный код. И выходит, что пока проект живет — мы только и делаем что его изменяем. Не знаю как для кого, но для меня идеальный код — это код который можно относительно безболезненно изменить.

Изменять код на который нет тестов — ну в пень, пусть этим занимаются люди, которые по ночам любят баги фиксить на проде, вместо того, чтобы спать. Поэтому все-же не соглашусь, что может существовать хороший код, и на него не будет тестов.

Задайтеся краще запитанням, як написати код, який потім без тестів та холодного поту можна міняти та рефакторити. Це цікава інженерна задача. Цікавіша за банальне формошльопство.

Просвети. Реально не знаю.

А які в тебе є ідеї? Які в твоїй роботі є найбільш незрозумілі речі, які не дозволяють тобі швидко рефакторити код?

Мабуть можливо, але лише обрані знають як :) Я ж пітримую «школу» Роберта Мартіна, хоч і не завжди ще виходить працювати по TDD

Тиск з боку бізнесу.

Не зовсім точне визначення.
Можна подумати, що бізнес тисне на програмістів, щоб вони писали поганий код.
Просто бізнес часто ставить програмістів в такі умови, коли писати ідеальний код неможливо (часті deadlines, регулярні зміни вимог)

Так, мається на увазі що бізнес висуває вимоги які підштовхують команду робити помилки.

вимоги які підштовхують команду робити помилки

А як вимога може підштовхнути команду робити помилки?

Легко. «Хочу кнопку, яка буде міняти користувачу його ID в базі». Ця вимога приведе до дикого оверхеду в коді з нульвою бізнес-цінністю. Точніше цінність буде негативною.

Також важливо не забувати, що код, який ми написали, ми самі ж і читаємо. Мій син полюбляє жарти про програмістів. Один з них звучить так: «Хто це такий код написав? О, так це був я...» :) Це до того, що з часом ми забуваємо, що писали й навіщо. І якщо код був не ідеальним, то потім виникають питання до нього.

Не зовсім згоден. Свій код програміст, може і з труднощами, але згадає і зрозуміє.
Тому чистий код повинні розуміти ІНШІ програмісти.

Ваше право. Я зутрічав людей які забувають, і сам забував

Але хто ж відповідає за якість коду? Роберт Мартін вважає, що лише програмісти. Одним з прикладів відповідальності він називає доволі свіжу історію з компанією Volkswagen. Великий скандал, який стався через маніпуляції з результатами показів викидів вихлопних газів автомобілів, щоб обдурити тестувальні апарати

Це не зовсім вдалий приклад, тому що справа Volkswagen — це не про неякісний код. Код-то працював правильно, як і хотіли програмісти, просто вся ця система обманювала покупця.

це про те — хто відповідає за код, Роберт Мартін вважає що ніякий «тиск бізнесу» не має бути виправданням до неякісного коду

Дякую за статтю, але було б непогано згадати дещо з теорії — що таке code smells, на які групи вони поділяються, і які є стратегії рефакторінга (і їх категорії).

Дякую вам за коментарі, радий що стаття підняли стільки питань, значить є про що замислитися. Що до

code smells

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

Тиск з боку бізнесу.

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

Відсутність розуміння наслідків технічного боргу.

В кого? В бізнесу? Йому чхати на ваші оці «борги».

Відсутність боротьби з жорсткою обмеженістю компонентів.

Конструктор.

Відсутність автотестів.

Як до сраки карі очі. Автотести не змінюють якість коду, просто дають хибне відчуття, що все під контролем. Борг може залишатися боргом при цьому.

Відсутність документації.

В документації може бути описаний шикарно спроєктований технічний борг. ;)

Відсутність взаємодії між членами команди.

Чхати, якщо у вас конструктор.

Довготривала одночасна розробка в кількох гілках.

Кон-струк-тор.

Відкладений рефакторинг.

Не потрібний, якщо у вас .... правильно, конструктор.

Відсутність контролю за дотриманням стандартів.

Конструктор не дасть не дотримуватися.

Відсутність компетенції.

Тут вже нічого не допоможе. Тут тільки шлях болю та страждання.

Тут вже нічого не допоможе. Тут тільки шлях болю та страждання.

А може конструктор?

Аж интересно стало — что такое конструктор? Вот реально вопрос даже не с иронией — может я чего упустил в новых трендах разработки?

Як до сраки карі очі. Автотести не змінюють якість коду, просто дають хибне відчуття, що все під контролем. Борг може залишатися боргом при цьому.

Угу, конечно, не изменяют. Я почему-то наблюдал вокруг себя обратное — те кто начал практиковать написание автотестов, начал как-то сам задумваться о важности слабой связанности и высокого зацепления, порой даже не понимая и не слышав об этих понятиях. Тем самым улучшая качество своего кода. Просто потому, что дико сложно написать тест на класс из нескольки тысяч строк лапшевидного кода, у которого связи со всем остальным кодом в системе.

Аж интересно стало — что такое конструктор? Вот реально вопрос даже не с иронией — может я чего упустил в новых трендах разработки?

Цим «новим» трендам розробки років більше, ніж нам с тобою разом. ;)
Зазвичай інженерам ліниво думати, тому вони вирішують задачі, як то кажуть, в лоб. Це простіше, не вимагає багато зусиль, та й взагалі імперативненько. Але такий підхід створює багато проблем потім, під час підтримки, розвитку, рефакторінгу. Щоб рефакторити було не так лячно, придумали тестування. Це логічний розвиток подій. Причина та наслідок.
Але, якщо розглянути задачу не як метелика-одноденку, а на трохи вищому рівню абстракцій, то можна виявити, що весь код на логічному рівні доволі таки повторюваний за операціями, різняться тільки деталі імплементації та порядок їх виконання. Один з яскравих прикладів — CRUD. Це 4 універсальні операції над даними.

Зазвичай CRUD імплементують в «прямому» порядку: є об’єкт та йому роблять імплементацію операцій по роботі з ним. Якщо порядок вивернути навиворіт та побудувати систему 4 типів операцій, то виявиться, що система в цілому стає трохи універсальнішою та в ній з’являються операції, які повторюються від імплементації до імплементації. Наступним логічним кроком буде об’єднання таких повторюваних операцій в окремий модуль/блок/систему/фреймворк. Код кінцевої імплементації в кожному конкретному класі чи функції стане простішим та лаконічнішим. В ідеальному випадку імперативний підхід перетворюється на декларативний. Вирішувати кінцеву задачу за допомогою декларативного підходу простіше, бо він майже не має градацій успішності в роботі, та працює за булевою логікою: працює або ні. І це зрозуміло вже під час розробки. І тестувати повторно це безглуздо. Можна, але економічно не виправдано.

Ще одним яскравим прикладом «конструктора» з десь з 50 річним випробувальним терміном, який доводить високу ефективність підходу, є так званий «*nix way». Це система примітивних утиліт, які побудовані за однаковими правилами та вимогами до вводу-виводу, з яких можна зібрати набагато більшу функціональність, ніж дозволяє кожна утиліта окремо. Якщо уважно придивитися до деталей, то ми можемо побачити абсолютно той самий підхід, що я описав вище.

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

У кожного свої стимули... Моїм стимулом було створити методологію, яка не вимагає тестування взагалі.

Привіт. Дякую що прокоментували мою статтю. Це класно що ви знайшли такий чудовий варіант вирішення усіх проблем, і круто якщо він дійсно працює. Можливо рівень вашого розвитку та самодисципліни дозволяє писати якісний код без тестів, але багато інших розробників поки що, на жаль, цього не можуть. Тому більшість досвідчених програмістів всього світу підкреслюють важливість юніт тестів та TDD.

До речі, можливо можна десь почитати про вашу систему?

Тому більшість досвідчених програмістів всього світу підкреслюють важливість юніт тестів та TDD.

Мільйони мух не можуть помилятися... :)

До речі, можливо можна десь почитати про вашу систему?

Немає системи в тому вигляді, яку можна споживати як срібну кулю крізь без винятків. Але деякі підходи я можу назвати

  1. Дешевою мусить бути модифікація коду, а не його написання
  2. Давати перевагу декларативному, а не імперативному
  3. Використовувати *nix way по можливості та максимально
  4. Спочатку розробляти методологію, а вже під неї обирати інструменти, а не навпаки
  5. Зводити функціональність модулів/методів/інтерфейсів/тощо до двох станів: працює та не працює
  6. Намагатися завжди писати fail safe та fault tolerant системи
  7. Розробляти абстракцію функціональної моделі перед тим, як створювати об’єктну
  8. Обробляти потоки абстрактних даних, а не конкретних
  9. Першими мусять бути інтерфейси, протоколи та контракти, а не кінцева об’єктна модель
Перераховувати можна ще довго, що швидко зміг згадати, описав. Це все призводить до зменшення важливості тестування як явища.
Тому більшість досвідчених програмістів всього світу підкреслюють важливість юніт тестів та TDD.

Більшість — це 5 чи 6? Двох знаю: Кент Бек і Роберт Мартин, а далі?

Їх тисячі, але головне — як каже Роберт Мартін, дисципліна розробки програмного забезпечення потрібна саме тому, що через дуже високу потребу в нових розробниках в професію приходить дуже багато новачків. І TDD це один з компонентів цієї дисціпліни.
Так, почитати) medium.com/...​nged-my-life-5af0ce099f80

Їх тисячі, але головне — як каже Роберт Мартін

і пророки Його.

І TDD це один з компонентів цієї дисціпліни.

«И все мы знаем этого человека» (tm)

Так, почитати) medium.com/...​nged-my-life-5af0ce099f80

Так, почитати) bormor.livejournal.com/790304.html
А усякі сміттєзбірники за paywallʼом, як medium, автоматично не вважаються джерелами.

Подписаться на комментарии