Як правити код дуже поганої якості?

Привіт усім. Зараз працюю з кодом, який не просто дуже низької якості, а дурниця рідкісна. Часто хочеться просто взяти все і переписати, але проєкт не маленький і на це ніхто не піде. Буває, навіть, десь виправив — в іншому місці зламалося. Дуже сильно страждає нервова система.

Що ви робите у такому разі? Чи потрібно звільнятися? Як виправляєте такий код?

👍ПодобаєтьсяСподобалось1
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

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

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

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

Копіпаста це норм, її можна менеджити. Ось приклад поганого коду який я бачив особисто:
— є система яка складається із ~200 лямбд
— кожна лямбда у своєї репі
— вони одна одну викликають майже «рандомно»
— виклики реалізовані через Гугл паб/саб та підписку на зміни у файлах на GCS
— ніякого зрозумілого патерну найменування івентів немає
— щоб було більш зручно назви івентів генеруються динамічно, по типу «мій_івент_{щось}», при тому константі частини назви майже не має сенсу шукати у сорс коді — вони надто поширені, із 100 матчів реальних 10
— ну тобто із допомогою статичного аналізу неможливо дізнатися яка лямбда яку викликає і навіщо
— дебажити можна лише у клауді і лише на реальних даних

:hidethepain:

Так зате кожна лямбда проста, як то люблять казати адепти мікросервісноі архитектури :)

А якщо серйозно — то я бачив такий підхід і в «монолітах» — коли хтось начитався про модель акторів, а у мові нічого не має для цього, і не зроблений/не використовується ніякий інфраструктурний фреймворк чи ліба для цього.

Ще й слухачі на ці актори — коли треба чипляються, коли не треба відчипляються. Красота простеньких класів /об’єктів :)

Так зате кожна лямбда проста, як то люблять казати адепти мікросервісноі архитектури :)

Я таке не казав :) там лямбди були більш як мікросервіси ... але на лямбдах

Трохи оффтоп.
Сама срака яку я бачив в коді, це коли назви всіх змінних в файлі складалися ТІЛЬКИ з нулів і літер О о. Ви б бачили це феєричне гівно, його не те шо правити, зрозуміти було неможливо...

я бачив назви функців та методів, які скорочувалися до аббревіатур, наприклад
def lol(..)
де lol розшифровується як list of lists, бо на виході з n вхідних формувався 1, як це було видно з коду, власне, хіба з коду про це і можна було здогадатися, бо докстрінгів не було жодних

Це зроблено навмисно, щоб було важче читати, розуміти, вносити зміни.

а сомому потім не страшно правити?

Ні, бо в автора завжди є необфускована версія.

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

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

Я не спец з js але здається він і сам там вміє жмакає все так що нічого не розібрати.

Ні, сам нічого не робить, але є купа пакетів з мініфікації або обфукскації.

Але якщо ідеться про роботу в команді, то як?

Команда працює з оригінальним, необфускованим кодом. На прод або замовнику відправляють «зіпсовану» версію.

В який момент обфуршені назви стають нормальними?

Зворотньої конвертації немає.

І як замовник не зможе кинути?

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

Як він буде приймати роботу?

Ви багато бачили замовників, які переймаються кодом? Проект працює? Працює.

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

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

Ну, я проходив аудит, двічі одного й того самого проекту в двох різних компаніях. Отримав від однієї оцінку «відмінно!», а від інших — «треба все переробити». Останні були... наша галєра, яка хотіла проект собі забрати. ;)

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

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

Підозрюю що код було перегнано через якийсь обфускатор
У здоровому глузді так би ніхто не написав. Бо просто написати такий код це та ще задача.

в нас був проект де програмісти вирізали по якомусь хитрому алгоритму стрічки з вихідного коду БД, то наша базовичка вирахувала той алгоритм та все відновила... мабуть вони про PL/SQL Wrapper-wrap.exe не знали...

А окрім жартів, є якісь ідеї (про які я не знаю) як робити так щоб було добре?

Поки найбільший інсайт в мене, що якість коду залежить:

а) ***************
б) ***************
в) від власного психоемоційного стану людини яка розробляє.

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

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

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

  • Я розумію, що робить функція, метод, класс, модуль?
  • Що мені подобається або не подобається в цьому коді?
  • Як його можна покращити (навіть якщо все подобається)?
  • Чи легко мені внести зміни в цей код?
  • Чи розумію я наслідки внесених змін?
  • Чи можна цей код перевикористати ще раз, чи він «одноразовий»?
  • Який рівень розробника потрібний, щоб робити зміни в цьому коді?

Також бажано читати про прості практики, які не потребують цілих книжок, щоб їх пояснити, але які є не менш ефективними, наприклад «Return earlier/first», коли метод припиняє виконання при першій ситуації, яка робить подальшу роботу безглуздою або непотрібною.


function foo (a){
  if (a == 0) return
  // Do some work here...
}
Замість

function boo (a){
  if (a != 0) {
    // Do some work here...
  }
}

Або паттерн «Make work during declaration», коли багато чого відбувається під час декларації змінних, щоб потім спростити код процедури/методу/функції.

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

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

Все погано, все дуже дуже дуже погано, і нічого хорошого вже ніколи не буде.

«саме тому ми радимо онлайн-сервіс Міндлу. міндлу — тільки досвідчені фахівці, які завжди вам допоможуть»

Я навіть не уявляю, як можна бачити щось нежахливе в цій дужковій мові впринципі ((((

мова тут не причому, справа в мене, я погана розробниця

Чи не пробувала просити когось робити ревʼю коду? Бо власне відчуття то одне, а сторонній погляд — це інше. Оскільки в кожного своя думка, можна попросити декількох людей о ревʼю й можна вжити ШІ для покращення якості коду.

хто вам таке сказав? ви самі? то дурня

Все нормально. Умовно гарний код буває лише на проектах де є топові, досвідчені архітектори, конвенції, полісі які обов’язково включені в загальні налаштування для всіх IDE розробників, та потім CI/CD який буде генерити помилку якщо у вас зайвий пробіл десь буде. І навіть таки налаштування розробки не гарантують ідеального продукту.
В інших випадках у всіх багато жахливого коду.
Залишається знайти гарного психотерапевта який навчить як не страждати від свого жахливого коду а пишатися ним.
Загалом якщо ви розумієте де і чому він жахливий це вже неабиякий прогрес. Деякі за все життя так до цього ц не доходять.

Зазвичай люди дуже прискіпливо ставляться до результатів власної праці та схильні до тотальної недооцінки власного рівня. Хтось окрім вас казав, що код поганий?

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

ти починаєш з того що ти не знаєш всіх умов

Для цього є додаткові рівні абстракції. Або рефакторінг.

Потрібно зʼясувати, чи те того варте. Якщо через півроку цей сервіс замінять на щось інше — немає сенсу.

Якщо не варто — то не варто.

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

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

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

Успіху :)

Немає ніяких таємниць.
Спочатку добре подумайте чи воно вам треба, чи краще себе пет-проект запилити. Якщо треба тоді:
По-перше, знайдіть або напишіть перелік UseCases
Потім, зробить порожню чисту архітектуру поруч. Класичну для вашої мови або фреймворка.
І потроху винносте в неї все через інтерфейси, базуючись або на UseCases або на TDD або на DDD або ще на чому завгодно, але тільки щоб ви точно розуміли, що ви робите.
Це формально і буде переписування але дуже маленькими кроками і контрольоване.

По-перше, знайдіть або напишіть перелік UseCases

Вже нереально у значній частині випадків.

Простий приклад: викликаємо спочатку X, потім Y. Ніяка документація не вимагає такого порядку. Але якщо навпаки, зʼясовується, що 1) в деяких версіях не працює через баг і 2) виникає обгін у взаємодії з іншою програмою. Більш того, здається, що Y викликати не треба. Але без цього працює не так.

І читанням коду з формуванням якихось міфічних usecases це зафіксувати неможливо.

Потім, зробить порожню чисту архітектуру поруч. Класичну для вашої мови або фреймворка.

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

Це формально і буде переписування але дуже маленькими кроками і контрольоване.

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

Немає ніяких таємниць.

:)))))

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

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

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

1) в деяких версіях не працює через баг і 2) виникає обгін у взаємодії з іншою програмою. Більш того, здається, що Y викликати не треба. Але без цього працює не так.

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

Ну то болото звісно, але не бачу тут чогось що не можна вирішити.

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

І ось таке ти методом «зібрати юзкейси» не знайдеш...

Може це той випадок коли не треба чипати.

В тому і справа, що розвивати — треба. Але не з нуля.

І ось таке ти методом «зібрати юзкейси» не знайдеш...

Це і є юзкейс, але вже не бізнес-рівня, а розробницького. ;)

1) Понять какие есть сценарии использования ПО
(Внимание — тут надо будет потрудиться, часто многие бизнес пользователи не понимают и 10% продукта)
2) Покрыть тестами.
Чтобы железно иметь индикатор факта работоспособности выявленных сценариев из п.1 и новых.
3) Шаг за шагом править. Итерационно, без штурмов и амбразур.
4) Все активности из 1-3 обязательно фиксировать в отчетах о проделанной работе.

Тут продакшен код з США, це гарний чи поганий код?

private static void updateAccountLater(List accountIds) {
updateAccountNow(accountIds);
}

швидше поганий.

з назви updateAccountLater ми не бачимо залежність від updateAccountNow
а в реалізації updateAccountNow ніяк не видко використання у updateAccountLater

Повинен був з’явитися метод для обох випадків, де Now та Later — вказується аргументом

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

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

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

Це абсолютно чітке поняття. Для цього є відповідні визначені критерії, та методи автоматизованої оцінки — як то статичні аналізатори коду.

Це абсолютно чітке поняття.

Ніт.

Для цього є відповідні визначені критерії, та методи автоматизованої оцінки — як то статичні аналізатори коду.

Нема «відповідно визначених критеріїв» без указання специфіки области.
Код для перемикання процесів у ядрі чи розвʼязку СЛАУ порушує більш ніж всі критерії якости коду для бізнес-логіки сайту, і навпаки.

Ну... метрикам коду, статичним аналізаторам вже як мінімум більше десяти років. Той факт, що вони не набули великої популярності означає, що або (1) розробники та менеджмент дурні; (2) користь від них умовна.

Рев’ю кода, наприклад, набуло популярності. Хоча інструменти з’явилися трохи пізніше, ніж статичні аналізатори та вимірювання якості.

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

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

Тобто? ESLint, pylint, SonarQube — це непопулярні інструменти?
Штуки типу cyclomatic complexity вони теж вміють вимірювати...

Вони вміють, просто на це дійсно хтось звертає увагу? Чи просто ставлять хінт.
ESLint, pylint це тузли для динамічних мов, більшою частиною вони потрібні, як на мене, щоб ловити описки в іменах. Це проблема та головна користь від них.
Про SonarQube нічого не чув, я далекий від світу Java.

Просто от щоб на мітингу менеджер проекту казав щось на кшталт «cyclomatic complexity» нашого проекту збільшується, що будемо робити?

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

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

Але маємо факт, що це не дуже поширилося.

? Я за останні 5 років не бачив жодного проекту де би не використовувались XP та кращі практики, зокрема і статичний аніліз коду.

Я за останні 5 років не бачив жодного проекту

Або дуже пощастило, або неправда.
Бо таких навкруги більше, ніж тих, де це все є.

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

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

Питання було не про «рефакторинг» а про те, щоб код лише пройшов перевірку аналізатором.

Знаю одну історію як дехто намагався відрефакторити код. Зайшов на проект де був єдиним бекенд розробником. Там була структура що не подобалася розробнику, багато дублікату і всяке таке, що очі різало. Вирішив то відрефакторити, поступово разом з виконанням задач, але не врахував що навантаження на проекті і дедлайни можуть зрости. Результат вийшов не дуже:
— частина коду відрефакторена стала в новій структурі, здавалось би ок...;
— деякий новий функціонал писав не по легазі код стайлу, а «типо по нормальному» з наміром бо перформанс буде кращий;
— почав виносити деякі куски в сервіси, репозиторіїї і т.д;

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

Це все я до чого: треба мати на увазі що можливо не треби пріорітезувати рефакторінг.
Тут були поради про інтегрейшн тести — з цього я б почав, тобто:
1. Інтегрейшн тести — покрити всі ендпоінти, консюмери, листенери і т.д
2. Спланувати рефакторінг, і ще раз подумати чи стане часу і терпіння довести до кінця. Бо якщо воно лишеться на середині може стати гірше.

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

Будь-який код це код дуже поганої якості

Вчиться правити, в цьому і є ваша робота.

Ну тут я не погоджуюсь існують критерії об’єктивної оцінки структурної якості ПЗ. Хороший код відрізняється від поганого в першу чергу простотою його модифікації, тобто усунення дефектів, додавання або прибирання нової функціональності.
Поганий — відомий як спагетті код — це слабо структурована мішаніна яка переплітається між собою (в нас розповсюджена назва гомнокод). Хороший код — він же лазанья код, це елегантно структурований логічно простий скріптінг, який просто модифікується і підтримується.
За Фредеріком Бруксом — бізнес завжди давить на час і на гроші, що часто призводить до створення продуктів — які після цього не можливо нормально підтримувати і зрештою насправді втрачає гроші.
Одна з головних передумов створення лазанья кода — це проектування від початку як процесс та чиста архітектура.

Є така штука як еволюція, це коли те припущення які ви мали коли робили

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

Перестають працювати, бо вимоги, потреби, масштаби, змінились. будь-який проєкт починається як чистий код, але цікаво подивитись на це через 10-15 років еволюції.

І це об’єктивна штука, бо якщо ви подивитесь на проєкти в мільярд років еволюції, там настільки horrible mess що вам і не снилось, але працює, і офигезно працює.

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

Та прикладів скільки завгодно, від UNIX і т.д.

Будь-який код це код дуже поганої якості

Тільки за умови невідповідности вимогам, які змінились з моменту його останньої правки, і в тій мірі, в якій ця невідповідність.

лямбда ліфтінг & статична типізація.

Як правити код дуже поганої якості?

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

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

Так за декілька років, можна значно покращити ситуацію)

Ще вам, певно, знадобляться тести) але це не обов’язково мають бути файні unit/integration tests, колись використовував bash скрипт, який робив запити через curl, зберігав купу html, а потім порівнював результити нової та старої реалізації.

Чи потрібно звільнятися?

Ви ж маєте розіміти, нащо вам усе це.
Чи ви хочете мати досвід вдалого/невдалого рефакторінку легасі, чи може ви взагалі хочете працювати з іншими (сучасними) технологіями.

Два борща цьому пану.

беремо якусь (невеличку) погану частину

Я не так робила — коли є задача, яка якимось чином торкається цієї «поганої частини» — то не просто робиш задачу, вставивши в старий гівнокод пару своїх красивих строчок, а покращуєш те що є (і ще навколо пару-тройку функций або весь файл) + робиш ту правку, яку запросив клієнт.

Таким чином, ти (чи QA) все одно ж будеш тестувати свою правку — заодно і протестуєш всі ці зміни. Можна навіть два pull requests прислати — один «рефакторинг» а другий вже «багфікс» чи що там тебе попросили зробити.

Ми так переходили з promises на async/await коли дістався чужий старий проект на промісах.

Розумію ваш біль, авторе.
Вчора попросили глянути баг на дуже старому проєкті, а я тільки й знаю, що приблизну назву таблиці в бд та репозиторій, в якому шукати.
Йду в базу глянути на ту таблицю, а там їх з подібними назвами цілих три з різними суфіксами)
Йду в код, а там по 3-4 методи з подібними назвами і різними суфіксами — типу, method, methodOld, methodV1, methodV2 і т.п.
Локально запустити не можна, на стейджі також працює далеко не все. Колега з того проєкту не знає, який з методів відпрацьовує — говорить, можна хіба відключити якийсь з них і подивитись, що відвалиться на проді і почекати, хто прийде скаржитись)

Я з цим вже борюсь напевно на протязі усієї професіональної кар’єри, коли заводять баги в стилі «Mozilla crashes — you suck!».
Вимагайте в описі дефекту три речи : шляхи відтворення, очікуваний результат і існуючий результат. І тоді ви зможете банально від дебажити той баг. При неможливості запустити локально, що нажаль буває дуже часто — додавайте логи і робіть printf дебаг. Тобто по логам ви зможете так само як і дебагером зрозуміти алгоритм роботи програми, та значення змінних. Відповідно знайти Root Cause of the issue та розробити шляхи усунення проблеми (так трудомісткість метода значно нижча, та він дуже надійний). Тобто найдете ту таблицю яку вам треба і т.д.
Усе перелічене в книгах які знизу.

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

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

від підтримки — швидко пропадає бажання працювати та віра у людство :)

як весело коперсатись в коді без документації

Нормальному коду навіть документація не потрібна. Нещодавно доєднався до проекту — типова «Clean Architecture» з репозиторіями, сервісами, ентіті, дтошками. Тупо від контроллера по методам через «go to implementation» пройшов і все зрозуміло.

Дивлячись яка, реквайменти не завадили би. Архітектура — must have.

скажіть йому — «нема коли пилу точити — пилити треба?»

Запитала на днях в колеги, де знайти логи проєкту. Відповів — ніде, логів немає 🤦‍♀️ Тобто, спочатку їх треба буде ще налаштувати.

Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.
Mosher’s Law of Software Engineering
Просто з ескалуйте начальству, скажіть — що оце треба без цього не пофіксимо, тому естімейт такий то. Також поясніть що таке логи тобто телеметрія і які бенефіти крім дебагінгу, наприклад налаштувати Buiseness Intelegence через утілити типу : Graphana, Dynatrace, Data Dog і т.д.

Докидуємо виклик логів в кожен метод. Якщо є кінцевий метод, який викликається завжди — логуємо обрізану версію debug_backtrace()

Мартін Фаулер — Refactoring. Код з найгіршою структурною якістю можна привести до ладу. Питання тільки в ціні цього. Як пише сам Мартін — бізнес ніколи за це не хоче платити, тому це треба роботи потаємно, по ходу роботи.
www.amazon.com/...​factoring ,aps,212&sr=8-1
Інша відома робота Working effectively with legacy code www.amazon.com/...​el-Feathers/dp/0131177052 від дядька Боба — Роберта Мартіна.

Мартін Фаулер — Refactoring. Код з найгіршою структурною якістю можна привести до ладу.

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

Але, тут багато питань.

1. Що таке лад? Вже це питання суб’єктивне. Плюс проект зазвичай єдиний, тому важко порівняти щоб би було. Зараз розповсюджені ORM, цей стиль звичний, він більш естетичніший. Але я не виключаю, якщо взяти один проект з ORM, а інший, наприклад, у Delphi стилі, та порівнювати кількість багів, час на виправлення, і т. п., то я не впевнений у результаті.

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

Питання тільки в ціні цього.

3. З урахуванням (2) це факт. Але... Навіть якщо можна буде математично довести, але якщо у нас вийде вартість у мільярди людино-сторічь, то з практичної точки зору це буде означати скоріше «не можна» ніж «дуже дорого».

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

Ну так консультації можна давати і про те, як писати нову версію з нуля, особливо як в неї закладати нову архітектуру ;)

Давати консультації не проблема, проблема це продати.

Так зараз вже продає.

Інша відома робота Working effectively with legacy code www.amazon.com/...​el-Feathers/dp/0131177052 від дядька Боба — Роберта Мартіна.

Я прям фігею як ви, прямо дивлячись на указання що автора звуть Feathers, називаєте його Робертом Мартіним...

Критерії якості можуть бути різними.

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

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

P.S.:
Розумію вас.

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

тобто з точки зору якогось SonarCube все OK,

Самий трешовий код бачив на проектах, де SonarCube був у merge hooks — люди комітали суцільний, жах, аби пройшов білд.

Я б порекомендував перед початком роботи з таким кодом почитати «Ідеальний програміст» Роберта Мартіна. Ця книга допомагає сформувати професійний підхід до написання і покращення коду. Вона пропонує стратегії для рефакторингу, роботи з технічним боргом, а також підхід до прийняття рішень, коли переписувати весь код неможливо. Це допоможе ефективніше вирішувати проблеми з поганим кодом і зберегти спокій у складних проєктах.

Очікування: я побудував дуже класну стратегію покращення низькоякісної legacy code base та слідую своєму плану.
Реальність: прибігає ефективний манагер та волає «ааа! все має бути зроблено вчора! який рефакторинг?!111»

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

у відповідь на хард пуш, треба давати естімейт — одразу.

Для цього треба мати А) яйця і Б) силу волі сказати «ні», а також В) здатність аргументувати.
Як показує практика, більшість не мають цих якостей.

Зараз працюю з кодом, який не просто дуже низької якості, а дурниця рідкісна.

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

те що створено до них, то якась чухня і її треба переписати

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

Часто тут питання в Bus Factor. Люди щось переписують часто бо гадки не мають — що скажімо робить якесь полотно коду джуніорів з Бангалору, написане 5-6 років тому. А там часто рівень студентів першого курсу — тобто дуже складно зроблено, через брак розвинутого логічного мислення. Чим вища кваліфікація програміста — тим простіше виглядає його код.
От народ просто починає з’ясовувати як працює программа рефактоінгом коду.

+ Not invented hire — тобто синдром несприйняття чужої розробки, теж має місце але рідше.

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

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

Це не потребує ніякого узгодження з менеджментом

Нажаль, не завжди. Якщо на проекті практикуються майже почасовий контроль естимейтів на кожну таску та код ревʼю в стилі «нащо ти змінив те що напряму не стосується твоєї таски», то «сховати капелюха» буде важкувато.

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

Буває, навіть, десь виправив — в іншому місці зламалося.

Так це означає, що твій код поганий.

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

Ділюсь лайфхаком — можна не працювати на проектах написаних індусами.

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

А ти точно краще перепишеш?))

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

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

Для начала почитать умные книжки. Например:
«Refactoring: Improving the Design of Existing Code» by Martin Fowler
«Working Effectively with Legacy Code» by Michael Feathers
«Code Complete» by Steve McConnell
После прочтения возможно появится понимание, что с кодом не все так плохо. Если не появится — то потренироваться на небольших некритичных задачах. Время на рефакторинг можно закладывать в текущие задачи по связанному функционалу и при этом обьяснять что как и зачем ты собираешься рефакторить. Аргументы написаны в книжках выше. Если получится «продать» рефакторинг — то делать.

А тобі заплатять за переписування?

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

Ну якщо тести написано так що вони тестя ь тоді да, але я бачив багато прикладів коли тести заради тестів які нічого не гарантують

Тести заради тестів — це норма, а не виключення. Це можливість нічого не робити та заробити більше.

А ще іноді на проектах бувають «flaky tests», котрі працюють не завжди, але випадково. Тобто кожен приблизно третій раз падають. Перестартували тест — він пройшов, працюємо далі. І ніхто в команді не підняв червоній прапорець, коли вперше побачив таку поведінку. Ось цей підхід я не розумію.

код, который кормит всю компанию не может быть

поганої якості

маячня. «працює» != «якісно»

якщо ви викличете таксі, приїде грязний старий жигуль, але довезе вас до пункту Б — ви скажете «о, яка якісна послуга»?

Компанія продає не якісний код, а продукт або послугу що працюють.

Допустим ты делаешь ремонт и нанимаешь электрика сделать разводку. Он задачу делает, свет горит, разведено по плану. Но разводка — полное говно, провода по диагонале, дырки в стенах по полметра в диаметре, синяя изолента на скрутках каждые 2 метра, и так далее и тому подобное. Примешь такую работу без вопросов? Точки доступа как в спецификации записано, напряжение везде правильное.

Я тобі задам зустрічне запитання, ти в своїй хаті у всіх комунікаціях впевнений, що вони проведені вірно, якісно та без косяків?

Ты, как заказчик поставил задачу электрику: вывести нужное напряжение в нужные точки. Он вывел. Вольтметром тыкаешь — все ок. Нагрузку включаешь — все ок. Полностью соотвествует спецификации. Электрик же продает услугу проведения электричества в указанные точки, а не способ разводки проводов.

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

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

Викликати електрика та примусити переробити за власний рахунок. Або викликати експертів, скласти акт невідповідності, подати позов та відшкодувати всі збитки.

Але, ще раз задам запитання, чому ви впевнені, що у вашій оселі все зроблено як треба?

Викликати електрика та примусити переробити за власний рахунок.

Он пришел, посмотрел — ничего током не бьется. Потому что по условия задачи это происходит случайно при непонятных обстоятельствах. Затем электрик потребовал оплату своего времени и такси в обе стороны.

Або викликати експертів, скласти акт невідповідності, подати позов та відшкодувати всі збитки.

Аналогично — они пришли и все хорошо. На тебя опять посмотрели как на дебила и ты опять заплатил за вызов.
Что дальше?

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

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

Аналогично — они пришли и все хорошо.

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

Якщо є проблема, її буде вирішено.

Вопрос в том, кем и за чей счет. Мы уже близки к финалу, я расскажу как это бывает в реальном мире.
Ты по знакомствам найдешь электрика, который берет за час работы в 10 раз больше предыдущего. Он придет к тебе в гости, посмотрит, порасспрашивает и выдаст гениальный в своей простоте вердикт: надо раздолбить все и добраться до проводки вот на этом квадрате со стороной в 1 метр.
Дальше ты вызываешь рабочих (опять таки дорогих, повредить проводку раздалбыванием штукатурки нельзя) и добираетесь до проводки. Где вы видите оплавленную изоленту.
Электрик тебе поясняет, что место соединения не было пропаяно, скрутка плохая и поэтому при включении большой нагрузки (чайник+микроволновка+холодильник) соединение проводов грелось что привело постепенному оплавлению изоленты. За 2 года изолента поплавилась полностью(поэтому 2 года было все хорошо) и провод стал контачить штукатурку, у которой теплоотвод лучше, поэтому она не плавилась и не горела. В обычных условиях это себя никак не проявляло. А вот при повышенной влажности(готовить борщ без вытяжки, 2й день подряд дождь на улице и так далее), штукатурка влажнеет и становится лучшим проводником чем обычно — поэтому тебя лупит током. Электрик запаяет соединение чтобы не грелось, обмотает термостойкой изолентой, возьмет баблос и уйдет. На прощанье скажет что такая херня вообще то может привести к пожару и по хорошему надо все переделать. Головняк по поиску твоей плитки(снятой с производства) попадание в оттенок краски(конечно же нет) ляжет на тебя, равно как и расходы по восстановлению. И это пятно на стене будет памятником твоей глупости до следующего ремонта.
----
А все потому, что хороший электрик продает не только «сервис провести провода между точками», но и обязательство проводить работы, следуя стандартам отрасли, и обычно так и делает(получается дороже). А заказчик контролирует не только результат, но и следование стандартам либо лично либо пригласив других специалистов для аудита. Аналогии с софтдевом может провести даже джун.
PS
Отдельно умилили пассажи про «а я подам в суд и виноватые за все заплатят», которые говорят о том, что ты никогда не имел дело с судом. Если коротко — вероятность что какие то деньги заплатят лет через 5 минимум и выплата затянется еще лет на 10 по 100 грн есть, но она невысокая.

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

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

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

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

Это абсолютно реальные случай. За уши притягиваешь ты фантазии про волшебный приборчик который «вжиик» и все померяет.
Равно как и фантазии про судебные перспективы.

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

В моей квартире сертифицированные электрики проложили проводку согласно проекту, сделанными сертифицированным архитектурным агенством(где даже пересчисленны ОСТы, которым надо следовать а такжи марки провода для каждого ответвления. Результаты работы проверены третьим специалистом. Это сводит риски описанных косяков к минимуму. Но да, стоит денег.

Викликати електрика та примусити переробити за власний рахунок. Або викликати експертів, скласти акт невідповідності, подати позов та відшкодувати всі збитки.

Ви в якому рожевому світі живете?) Через пару років 99% електриків пошле на*уй зі словами «чувак, пройшло N років, я там знаю що ти за ці роки зробив?»

А, і ще одне питання: ви колись робили ремонт? Якщо так — у вас є повний завірений план ВСІЄЇ проводки в домі, згідно всих норм, з підписами та печатками електрика? Бо якщо ні — то про який акт та позов може йти мова

А якщо жигуль везе через Тису, або з Торецька в Краматорськ, тоді що скажете?

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

якість коду — це не просто про «комфорт розробника», це в тому числі його гнучкість та адаптивність. якщо завтра вийде 0-day в твоєму фреймворку/версії php/тощо, а код таке лайно що апгрейд займе 2 тижні і породить кучу багів — от тоді і видно буде, як заспіває бізнес

або завтра відвалиться payment gateway, і треба буде ШВИДКО перейти з умовного stripe на paypal. а девелопери скажуть що це займе пів року, тому що там насрано по принципу «ну працює ж!»

та короче, якби якість коду не мала значення і воно «аби працювало» — то весь FAANG писав би через змінні $x та $pzkcvjrj. в реальності ж, після певного масштабу, якість коду тісно повʼязана з грошима

якість коду тісно повʼязана з грошима

Тільки не в кращу сторону. Це велика хиба думати, що якість коду прямо пропорційна зменшенню витрат. Архітектура — так, може давати великий профіт шляхом зменшення витрат на модифікацію коду та написання нової функціональності. Але це не про якість коду.

Давайте проведемо простий експеримент. Візьмемо проект, якому 5 років. Чи зменшився у вас час впровадження нової функціональності у порівнянні з тим, що було 4 роки тому? А завдяки чому?

Навіщо експеримент, я вам наведу реальний досвід. Працював на проекті де було з десяток API інтеграцій, всі інтеграції досить однотипні (data scraping). Але було написано «аби працювало», то ж кожна нова інтеграція займала місяць-півтори

В якийсь момент плюнули, і виділили місяць на глибокий рефакторінг: нова структура, інтерфейси, ітд.

З того часу кожна нова інтеграція вкладається в два тижні, часто навіть швидше.

Інший приклад, був фронт на jquery. Лапша така що п**ц, додати нову модалку — це три дні болю та багів. Додавили клієнта, переписали на Vue. Швидкість розробки виросла на порядок, ті тікети що естімейтили (до рефакторингу) на тижні — зробилися за дні

якість коду прямо пропорційна зменшенню витрат

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

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

Плюсую. Кожен наступний, хто приходить на проект, буде казати «Яка ж тут срака з кодом, хто так пише? Переписати негайно!». Але це все про звички та упередженість. Я використовую фреймворк, який мені дає можливість працювати в 5-10 разів швидше за аналогічні рішення на React. Але будь-хто зі знанням тільки Реакту буде казати, що треба негайно переписати, бо йому незрозуміло.

Свій велосипед

Який свій велосипед? Фреймворк — має документацію. Нормальні рішення — мають свої паттерни

А взагалі, якщо ви фанат методу «х*як-х*як і в продакшн, головне що працює» — то на здоровʼя :)

Хоспаді, та фреймворк модна «готувати» ДУЖЕ по різному. Іноді дивишся що в прогресивній сімфоні понаробили і плакать хочеться

Ну то давайте всі писати свої велосипеди, раз фреймворки також не гарантують стандартизації

Який свій велосипед? Фреймворк — має документацію.

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

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

В якийсь момент плюнули, і виділили місяць на глибокий рефакторінг: нова структура, інтерфейси, ітд.

Ви не якість коду покращили, а архітектуру проекту.

Інший приклад, був фронт на jquery. Лапша така що п**ц, додати нову модалку — це три дні болю та багів.

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

Якість коду пропорційна стійкості.

Стійкості до чого?

Стійкості до чого?

До форс-мажорів

1) На*бнувся сервер, треба передеплоїти. А код гімно, бо скрізь захардкожені системні шляхи, апі-ключі, ітд. весь цей час у нас downtime. Системи пакетів нема, які треба версії під новий сервер — не зрозуміло. Але ж працювало!

Тим часом якісна система конфігурується одним .env файлом, та використовує пакетні менеджери. Годинка роботи — і зараз сервіс працює на AWS, а завтра на DO

2) пішло навантаження, треба додати cache layer. а код такий, що всі виконавці як бачать — або відмовляються робити, або ставлять естімейт в пів року. весь цей час сайт лежить. АЛЕ Ж РАНІШЕ ПРАЦЮВАЛО!!!

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

3) змінився vendor. наприклад, вчора відправляли всі листи через SES, а сьогодні амазон забанив, і треба світчитись на mailgun. а скрізь по коду гвіздками прибито function sendAmazonEmail() і прямо там же і html збирається, і в базу ходять, ітд. ОЙ, А РАНІШЕ Ж ТАК ГАРНО ПРАЦЮВАЛО!

Тим часом в тому ж laravel треба... змінити 3 рядка в енві: мейл драйвер, та апі ключі

Тому повторюся в останній раз «працює зараз» <> «зроблено якісно»

Тим часом якісна система конфігурується одним .env файлом

Яка тут кореляція до якості коду самої системи?

пішло навантаження, треба додати cache layer.

Складність додавання кешування на проект не залежить від якості коду, а повʼязано з архітектурою системи.

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

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

а скрізь по коду гвіздками прибито function sendAmazonEmail()

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

Зазвичай ви більше не викличете це таксі, та компанія збанкрутує. Це ціна неякісної послуги. Тут ніби-то компанія купу часу на ринку.

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

Якщо є альтернативи — так. В реальності ж може бути продукт — гімно, але альтернативи нема, і його юзають

Правда юзають до моменту, поки не зʼявиться конкурент з такими ж фічами, тільки якісно

Якісно фічі зроблені, чи якісний код написаний? Користувач то взагалі не бачить, що у вас там під капотом...

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

Якщо ні — то ми тут всі довбо**би які мусолимо щось про KISS, DRY, паттерни, ітд замість того щоб брати, і херачити все в один рядок через змінні x, y, data, test

Ну... з точку зору Мартина Фаулера, думаю що код Linux Kernel буде повним лайном. Тут проблема ще у тому, що визначень, що таке лайно немає.

А хто вам сказав, що ви пишете незабагований високоякісний продукт? ;)

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

Якщо ні — то ми тут всі довбо**би які мусолимо щось про KISS, DRY, паттерни, ітд замість того щоб брати, і херачити все в один рядок через змінні x, y, data, test

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

Якщо ціна в 10 раз менша, то це якісна послуга

Якщо довіз, то послуга вважається виконаною.

код, который кормит всю компанию не может быть
поганої якості

Пане, ви не знаєте як це працює.

1. Для більшості компаній код це просто допоміжна тулза, щоб умовний інвойс не в екселі самому рахувати а щоб рахувалось «само».
На таких проектах що гавно код що ні, це має малий вплив на кінцеві фінансові результати.
2. Переважна більшість компаній не прибуткові, а просто спалюють гроші інвесторів, успішні з меншою швидкістю, неуспішні з більшою.

Судячи по ваших прикладах, ви однобоко сприймаєте світ ;)

Судячи по ваших прикладах, ви однобоко
сприймаєте світ ;)

Так просвітіть сліпого=)

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

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

Буває, навіть, десь виправив — в іншому місці зламалося.

Ну... це проблема в розробнику... Читай уважніше код.

Часто хочеться просто взяти все і переписати

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

Ну... це проблема в розробнику... Читай уважніше код.

У вас досвiду 2 мiсяцi в програмуваннi?

виходить, що він непоганої якості, це просто складність задачі.

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

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

Виглядає так як будто ви не працювали з кодом iндусiв, або у вас дуже мало досвiду.

Читаю цю гилку, ржу шо капець ))) Вибачте, але не втримався

патерни проектування, SOLID, книжки про те як писати норм код

це лайно вигадано і написано отими самими шо гавнокодять

кодом iндусiв

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

У вас досвiду 2 мiсяцi в програмуваннi?

Десь 30+ років, а пам’ятаю часи, коли на PHP саме так й писали, та ніхто це не називав лайном.

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

Ну... на мій погляд, не зовсім так... рефакторінг, паттерни програмування, SOLID це все зі світу ООП. І з’явилося воно коли з’ясувалося, що створювати ООП архітектуру не дуже просто, та часто заводить у глухий кут. Воно все прийшло зі світу Java, у той час як, наприклад, embedded розробники працюють як і працювали колись, без усього цього.

Якщо я правий, та цьому коду 20+ років, то це означає, що інші люди підтримують його 20 років, та розуміють. А це досить непоганий результат. Не виключено, що якщо там було би кастомне ООП рішення з паттернами, то воно не працювало би 20+ років, та більшість була не в змозі з цим розібратися.

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

Виглядає так як будто ви не працювали з кодом iндусiв

Ні, не працював. Більшість індусів були або тестувальниками, або підтримка. Але чому ви так пишете, ніби-то це щось обов’язкове? Більшість коду, з яким я працював, було нормальної якості. Самі жахливі приклади у мене були як раз з ООП (особливо дивне наслідування в Simula-like мовах), а не такий плаский код.

І з’явилося воно коли з’ясувалося, що створювати ООП архітектуру не дуже просто, та часто заводить у глухий кут.

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

дані чудово описують три нормальні форми та реляційна теорія

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

А якщо спрощення не робити, то швидко настає колапс через надлишкові рівні абстракції.

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

дякую, не треба мене вчити проектувати БД :)

А до чого тут БД? Ми про ООП розмовляли.

ми розмовляли про моделювання даних у реальному світі, реляційна теоря тут все вирішує ще з 70-х, це все що я казав

Реляційна модель дозволяє вирішити тільки частку проблем. Одна з проблем, яку вона не може вирішити — занадто велика кількість реляцій. Друга — квантові стани. Третя — динаміка змін.

Друга — квантові стани.

И вытягивать энергию из черных дыр реляционная модель тоже не умеет :)))

Квантові стани зустрічаються в житті частіше, ніж ви думаєте. Ви коли насипаєте в миску їдло не знаєте, буде його кіт їсти чи ні. В просто виконали свою частину «договору».

якщо так чомуб не писати гомнокод всiм i всюди, нашо тодi код рефакторiнг, патерни проектування, SOLID, книжки про те як писати норм код?

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

найшвидший код завжди найубогішим чином написаний і це база

Він нормально написаний, відповідно до поставленої задачі ;)

найшвидший код завжди найубогішим чином написаний і це база.

Я надіюсь ніколи в житті не працювати з вашим кодом

я бачу пан пише ПО для ядерних реакторів, не меньше) 😆😆😆

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

найшвидший код завжди найубогішим чином написаний і це база.

Код ядра линукса открыт и она работает достаточно быстро. Найдешь там говнокод?

там чувак явно проектує системи рівня бортового корабля для місії аполон, це як мінімум) куди там ядру лінукса, ти шо. Поки не переіменуєш всі змінні в одну-дві букви, та не прибереш зайві таби — літати не буде!

Найдешь там говнокод?

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

unsigned long mstart, mend;

mstart = image->segment[i].mem;
mend   = mstart + image->segment[i].memsz;

Ну... Якщо брати світ Java, то тут будуть питання до іменування, ми бачимо скорочення, там більше звикли до

unsigned long memory_start, memory_end;

memory_start = image->segment[i].memory;
memory_end   = memory_start + image->segment[i].memory_size;

Потім скоріше за усе вони виділять окремий клас

struct memory_region {
    unsigned long start;
    unsigned long end;
};

struct memory_region memory_region;
memory_region.start = image->segment[i].memory;
memory_region.end   = memory_region.start + image->segment[i].memory_size;

потім буде функція

struct memory_region {
    unsigned long start;
    unsigned long end;
};

void init_memory_region_from_start_and_size(
    struct memory_region * self, 
    unsigned long start, 
    unsigned long size)
{
   self->start = start;
   self->end = start + size;
}

struct memory_region memory_region;
init_memory_region_from_start_and_size(
    &memory_region,
    image->segment[i].memory, 
    image->segment[i].memory_size);

І т. д. і т. п. А далі буде великий флейм, бо особливо мені початковий варіант подобається набагато більше, ...

Якщо брати світ Java

Старший брат капитана очевидность, адмирал ясин буй подсказывает что там не мир Java. Там мир С, в котором есть свои стандартные аббревиатуры паттерны, которые обусловлены как историческими так и вполне практическими причинами. Натягивать сюда джаву — ну можно сову на глобус попробовать натянуть :)

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

Отнюдь, есть вполне обьективные метрики выражаемые цифрами. Длина функции в строках — одна из них, цикломатическая сложность — другая и так далее по учебникам. Есть корреляция метрик к языку программирования.
Ну и есть универсальная метрика, WTF/Min: miro.medium.com/...​YhINS70gJpvT6ZeI09UA.jpeg

Ну... дивлячись що вважати гівнокодом... Якщо брати догми Фаулера, Мартіна, то там можна знайти довгі функції, незрозумілі назви, скорочення (бо на рівні embedded точна назва це коротесеньке оповідання), ... відсутність паттернів, ... Усе що я бачив, це на рівні флуду та роздуванню щік.

там можна знайти довгі функції

Где? Может там цикломатическая сложность гдето выше 7ми(код анализаторов не натравливал, глазами смотрел по диагонале — не видел)?

net/wireless/core.c

Десь 350 рядків. Але тут знову, для мене це ОК, для інших не ОК.

До речі, чи рахують аналізатори #ifdef?

Десь 350 рядків. Але тут знову, для мене це ОК, для інших не ОК.

Формально это плохо. Может некому зарефакторить, а может критично.

До речі, чи рахують аналізатори #ifdef?

Вот шо мне чатжпт про pvp-studio ответил(коротко: properly handles, гг):

PVS-Studio handles macros in C through a combination of preprocessing and static analysis techniques. Since macros can introduce complexities and obfuscate the code, proper handling is critical to avoid false positives or missed issues. Here’s how PVS-Studio deals with macros:

1. Macro Expansion: PVS-Studio expands macros during the preprocessing stage, just like the C compiler. This allows the tool to analyze the resulting code and detect errors that might be hidden within macro definitions.
2. Warnings for Complex Macros: The tool can issue specific warnings if macros are overly complex or prone to misinterpretation, helping developers identify areas where macro usage might cause problems or reduce code readability.
3. Tracking Macro Definitions: PVS-Studio keeps track of where macros are defined and used. It flags potentially unsafe macro usage, such as those leading to side effects (e.g., macros that modify variables or rely on non-obvious behavior).
4. Handling of Preprocessor Directives: The tool also properly handles preprocessor directives like #ifdef, #define, and #undef, allowing it to analyze code conditionally included via macros.
5. Macro Redefinitions: It detects issues like macro redefinitions that could introduce inconsistencies, which are often difficult to spot manually.

While PVS-Studio effectively analyzes macros, it also encourages best practices, such as avoiding complex macros and opting for inline functions when possible, to improve both code quality and maintainability.

Формально это плохо. Может некому зарефакторить, а может критично.

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

PVS-Studio expands macros during the preprocessing stage,

Таким чином, якщо у мене 10 опцій, кожна з яких має два значення, то для того, щоб перевірити усі комбінації треба запустити аналізатор 1024 раз? Зрозуміло.

Якщо думати про рефакторінг, то виникне питання, де розбивати, як називати частини, як передавати контекст.

Это не джава. Тут вопрос номер один — перфоманс, который может крепко просесть, если думать об именовании и контекстах.

Таким чином, якщо у мене 10 опцій, кожна з яких має два значення, то для того, щоб перевірити усі комбінації треба запустити аналізатор 1024 раз? Зрозуміло.

Подозреваю что можно просто задать конфиг и пойти пить кофе. Я также подозреваю что разработчики одного из самых популярных коданализаторов для С/С++ и других языков, имеют чуть больше опыта в анализе кода, чем среднестатистический джава девелопер на доу, которому «все понятно».

Подозреваю что можно просто задать конфиг и пойти пить кофе. Я также подозреваю что разработчики одного из самых популярных коданализаторов для С/С++ и других языков, имеют чуть больше опыта в анализе кода, чем среднестатистический джава девелопер на доу, которому «все понятно».

Ну...

1. Я більше С розробник.

2. Я просто аналізую відповідь

PVS-Studio expands macros during the preprocessing stage

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

3. Якщо це так, то є багато пояснень чому: (а) це простіше; (б) препроцесор вже написаний; (в) для С++ препроцесор вважається застарілим, та майже не використовується, тому немає великої потреби; (г) буде багато шуму на комбінаціях, які ніколи не можуть зустрітися, ...

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

2. Я просто аналізую відповідь

Ответ chatgpt — было бы интересно, а не «поговорить» — сходил бы на сайт, почитал доки.

Що ви робите у такому разі?

Це залежить не від коду, а від проекту, компанії, твоєї ролі на проекті і твоєї зарплати.

Якщо ти бачиш майбутнє за цим проектом/компанією, якщо твоя позиція і експертиза дозволяє приймати стратегічні рішення рівня «що ми далі робимо», якщо тебе влаштовує зарплата, то плануй і перероблюй.

Якщо ти сидиш весляром на галері на позиції мідла з середньою по лікарні зарплатою то просто звалюй, воно того не варте.

тим не менш проєкт працював, не така і

дурниця

виходить)

Boy scout rule, або «активне читання коду». Тобто коли розбираєшся що ця функція робить — не тримаєш в голові що це таке — а одразу її перейменовуєш більш зрозуміло. Банально нормальний неймінг вже знімає 50% головного болю. Виносиш куски в функції, розбиваєш на файли, ну коротше увесь оцей простий рефакторинг який гарантовано не ламає написаний код й практично не займає часу. Якщо так буде робити уся команда — результат буде точно. Але якщо це та сама команда що цей код й написала, то я б на це не сподівався...

Робити повноцінний рефакторинг такого, тобто переписувати код — ну нафіг, воно того не варто.

доповню: опишіть гарно тестами, розбийте на модулі / компоненти, виносьте поступово окрему функціональність в окремі методи / класи згідно з Single responsibility і так крок за кроком можна зробити щоб стало краще

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

Можно пересесть на другой проект. Знаю чуваков, которые на проекте 1 неделю отработали и уволились, то что код спагетти и архитектура трэш. Другой заказчик нанял индусов, те ему написали проект аналогичной структурой ( в одной папке файлы css, коннекты к базе, пароли, js, темплейты) заказчик попался адекватный, признал свой факап, все индусское говно выкинули и написали красиво на фреймвоврке

Буває, навіть, десь виправив — в іншому місці зламалося. Дуже сильно страждає нервова система.

То не виправляй якщо працює і не просили міняти.

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

Обычно стоит начать с сбора требований если их нет и покрытия интеграционными тестами чтобы уменьшить риски связанные с рефакторингом

А які у вас критерії поганого коду? Констурктивні а не «хочеться взяти і переписати»

Хочаб те що код погано читається, а так взагалi то критеріїв багато.

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

І як це тобі вдалось переписати код який просто погано читається, так що поламалось в іншому місці?

оо, пан видно не мав досвіду з РЕАЛЬНИМ гімнокодом

сценарій такий:

— відкриваємо код, бачимо змінну $tmplDtName
— думаємо «х*йня якась, погано ж читається. зараз переіменую, а перед тим перевірю, чи ніде вона більш не юзається. що може піти не так?»
— переіменовуємо
— все упало, бо нижче по коду є шмат лайна типу $name = ’tmpl’ . $x; $data = $$name;
— матюкаємось, фіксимо там
— десь упало в іншому місці, бо ВИЯВЛЯЄТЬСЯ, наш файл рандомно імпортять ще в трьох місцях, і очікують оригінальне імʼя. причому роблять це динамічно, через конкатенації, тому ні IDE, ні тупо grep про це не в курсі

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

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

Я бачив код в якому десь глибоко захована логіка, що базується на get_defined_vars. Типу, ти десь оголосив змінну з «правильним» форматом імені — херакс, на головній сторінці зʼявилась кнопочка. Де воно реєструється, як воно підтягується, скільки є тих кнопочок — бери шукай дебагером, приємного робочого дня 😁

впевнен автор ідеї курив те шо в нас зара вже легалізовано

автор був чи-то пакистанець, чи то індус, щось таке. короче, це була класика апворка: «ой, у нас був такий гарний Ранджеш/Махмуд, а зараз він пропав, і нам би оце одну кнопочку додати»

тоді питань більше не маю, ті таке смалять шо аж гай гуде

та ото ж, так смалять шо аж прикоптилися 😅

Типу, ти десь оголосив змінну з «правильним» форматом імені — херакс, на головній сторінці зʼявилась кнопочка.

Певно автор колишніц ембеддер сішник — там часто подібне практикують ( типу #define IS_OUPUT_ENABLED 1)

Тільки в С зазвичай ці макроси виносять в окремий headerfile та документують коментарями (або вони взагалі автоматично генеруються якимось configure скриптом)

Як добре що у джаві такого нема😂
Якісь незрозумілі конкатенації і динамічні імена🤦‍♂️

Ви ще часом не робили git blame і не шукали авторів?)

А скільки вас людей в команді? Проект прибутковий? Там просто код поганий чи ще і старі технології? Що інші люди думають про це в команді вашій і з боку клієнта?

Ви ще часом не робили git blame і не шукали авторів?)

Нi.

Проект прибутковий?

Не знаю менi таке не скажуть

Що інші люди думають про це в команді вашій і з боку клієнта?

Не питав

А скільки вас людей в команді?

На проект поставили тiльки мене.

Не питав

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

Треба виходити із того, що ніхто нічого міняти не буде. Далі задайте собі питання чи готові ви ще рік так працювати, якщо ні чи готові ви працювати рік за X% до ЗП. Якщо не готові, то не варто себе мучити, просто шукайте нову роботу. Є різні люди, різні ситуації в житті) Якщо вирішите залишитись, то із часом буде легше бо більше знатимите що і де може впаcти і тд. Ну і як уже тут писали, можна під час якогось фіксу чи фічі трошки це покращувати в розумних межах при можливості. Як правило, одного разу кастомер прийде із фічою, на яку треба буде рік часу або взагалі буде не реально зробити саме через тех, борг, і тоді або він почухає репу і почне щось робити із тим, або найме команду умовних «індусів», які йому пообіцяють золоті гори і що все зроблять за місяць часу)

Ви ще часом не робили git blame і не шукали авторів?)

Головне не вийти на себе😁

Часто хочеться просто взяти все і переписати,

Це як запустити в нього обсєрмат? З таким же результатом :)

Зазвичай це якраз той випадок коли ініціатива наказуєма

Що ви робите у такому разі?

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

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

​1. Настоять перед начальством, что при таком коде требуется выделение полосы времени и прочих ресурсов (например, «10% от каждого спринта») на процедуры устранения накопившегося технического долга, включая разбор, документирование текущего, покрытие тестами, рефакторинг.
Если такого не дают — ставить себе задачу уходить с проекта и искать что-то более-менее приличное. Иначе выгоришь за год.

Это самый сложный этап. Иногда требует высочайших дипломатии и умения корпоративных интриг.

​2. Когда время начало выделяться: по описанному принципу: разбирать код, описывать, что он делает и почему (не жалеть слов), писать тесты на предполагаемую функциональность. Уже на этом этапе можно найти много ситуаций, когда какие-то тесты будут не проходить. Это может послужить хорошим примером, почему вообще надо было это делать. Или не послужит, если заказчику плевать (такое сплошь и рядом, например, «мы не будем тратиться, чтобы это заработало после конфигурирования и без ребута»).

​3. Имея подкрепление кода тестами, можно смело рефакторить к нужному виду.

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

В частности, это будет и ответом на:

Часто хочеться просто взяти все і переписати, але проєкт не маленький і на це ніхто не піде.

Вариант «переписать всё» не должен рассматриваться на данном этапе в принципе, а и далее это обычно не нужно. Есть много примеров, когда попытка переписать с нуля заканчивалась просто отсутствием ресурсов и потерей интереса, а если и делалось, то часто терялись многие важные фичи прошлой версии. Не надо так. Для переписки с нуля нужны какие-то совсем суперпричины (ну например как меняли DBF-базы данных на SQL).

Именно что итеративно, на каждом этапе сохраняя всю функциональность и если что-то и удаляя, то полностью сознательно, а не потому, что не успели.

Спасибо за развернутый ответ.
Но это если рассматривать все с точки зрения Legacy, но не всегда Legacy так уж плох.
А если там что то типа такого —

 $npr = 'nopriv'; $fatl = ' error'; $e = 23; $v = 1; $c = 20;
 $mysql = new mysqli($h, $u, $db_p, $name);
echo "<td class='Field'  width='40'style='vertical-align: middle;'><b>II</b></td>\n";
			 $s_n = 0;
		$s_nf = 0;
			$s_f =  0; $s_n_pl = 0;
			 $s_nf_pl =   0;
			  $s_f_pl = 0;
		 for ($i=0;$i < count($ids);$i++) {
			$key=  $w_dates[$z]."|2|".$ids[$i];
			  $s_n =   $s_n + $w_n_s[$key]*1;
			 $s_nf = $s_nf + $w_nf_s[$key]*1;
			$s_f = $s_f + $w_f_s[$key]*1;
			$s_n_pl =  $s_n_pl+  $w_n_s_pl[$key]*1;
			 $s_nf_pl = $s_nf_pl +  $w_nf_s_pl[$key]*1;
			$s_f_pl = $s_f_pl + $w_f_s_pl[$key]*1;
	if ( $edti_stat[$key]==1){
				echo "<td class='Field'>".OutNF($w_n_s[$key],
$w_nf_s[$key],$w_f_s[$key])."</td>\n";
			}
$user = mysqli_query($connect, "SELECT * FROM user WHERE id = '{$id_polzot}' ") or die ("e_1110");
if(mb_strpos($word, $s)!==false || mb_strpos($word, $s)!==false || mb_strpos($word, $s)!==false){
$good[]=$s1;
}
			if ($edti_stat[$key]==0){
		          $link_dat = explode("|", $key);
				$link_dat2 = $link_dat[0];
				 $link_dat3 = $link_dat[1];
			    echo "<td class='Field'><a target='_bland' href='index.php?do=show&formid=64&p0=".$link_dat2."&p1=".$link_dat3."'><b style='color:#aa0000;'>".OutNF($w_n_s_pl[$key], $w_nf_s_pl[$key],$w_f_s_pl[$key])."</b></a></td>\n";
			}

З таким працювати — себе не поважати

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

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

Такое говно нейросеточка может поправить

<?php

// Improved variable names
$noPrivilege = 'nopriv';
$fatalError = ' error';
$errorCode = 23;
$version = 1;
$constant = 20;

// Database connection
$mysqli = new mysqli($host, $username, $dbPassword, $dbName);

echo "<td class='Field' width='40' style='vertical-align: middle;'><b>II</b></td>\n";

// Initialize counters
$sumNormal = 0;
$sumNonFatal = 0;
$sumFatal = 0;
$sumNormalPlanned = 0;
$sumNonFatalPlanned = 0;
$sumFatalPlanned = 0;

for ($i = 0; $i < count($ids); $i++) {
    $key = $workDates[$z] . "|2|" . $ids[$i];
    $sumNormal += $workNormalSum[$key] * 1;
    $sumNonFatal += $workNonFatalSum[$key] * 1;
    $sumFatal += $workFatalSum[$key] * 1;
    $sumNormalPlanned += $workNormalSumPlanned[$key] * 1;
    $sumNonFatalPlanned += $workNonFatalSumPlanned[$key] * 1;
    $sumFatalPlanned += $workFatalSumPlanned[$key] * 1;

    if ($editStatus[$key] == 1) {
        echo "<td class='Field'>" . OutNF($workNormalSum[$key], $workNonFatalSum[$key], $workFatalSum[$key]) . "</td>\n";
    }

    // Use prepared statements to prevent SQL injection
    $stmt = $mysqli->prepare("SELECT * FROM user WHERE id = ?");
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $result = $stmt->get_result();
    if (!$result) {
        die("e_1110");
    }

    // Check if the word contains the substring
    if (mb_strpos($word, $substring) !== false) {
        $good[] = $substring1;
    }

    if ($editStatus[$key] == 0) {
        $linkData = explode("|", $key);
        $linkData2 = $linkData[0];
        $linkData3 = $linkData[1];
        echo "<td class='Field'><a target='_blank' href='index.php?do=show&formid=64&p0=" . $linkData2 . "&p1=" . $linkData3 . "'><b style='color:#aa0000;'>" . OutNF($workNormalSumPlanned[$key], $workNonFatalSumPlanned[$key], $workFatalSumPlanned[$key]) . "</b></a></td>\n";
    }
}
?>
Ну а дальше да, ручками уже сидеть, разбираться

Тут просто руки чешуться якийсь інжекшн вхγярить

Уже намного лучше, но нет гарантии что что то не сломается. Особенно когда такого кода много.

Гарантія — це ви. Ваша робота, щоб не зламалось.

Запахло вордпресом 2010 року ))

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

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

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

И окупились твои нервозатраты, усилия привести все в порядок?)))

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

ChatGPT так виправив цей код й скоментував його:

$npr = 'nopriv';
$fatl = ' error';
$e = 23;
$v = 1;
$c = 20;

// Database connection
$mysql = new mysqli($h, $u, $db_p, $name);

// Output table header
echo "<td class='Field' width='40' style='vertical-align: middle;'><b>II</b></td>\n";

// Initialize summary variables
$s_n = $s_nf = $s_f = $s_n_pl = $s_nf_pl = $s_f_pl = 0;

// Loop through each ID
foreach ($ids as $i => $id) {
    $key = "{$w_dates[$z]}|2|{$id}";

    // Increment summary values
    $s_n += $w_n_s[$key] ?? 0;
    $s_nf += $w_nf_s[$key] ?? 0;
    $s_f += $w_f_s[$key] ?? 0;
    $s_n_pl += $w_n_s_pl[$key] ?? 0;
    $s_nf_pl += $w_nf_s_pl[$key] ?? 0;
    $s_f_pl += $w_f_s_pl[$key] ?? 0;

    // Output based on edit status
    if ($edti_stat[$key] == 1) {
        echo "<td class='Field'>" . OutNF($w_n_s[$key], $w_nf_s[$key], $w_f_s[$key]) . "</td>\n";
    } elseif ($edti_stat[$key] == 0) {
        $link_dat = explode("|", $key);
        $link_dat2 = $link_dat[0];
        $link_dat3 = $link_dat[1];
        echo "<td class='Field'><a target='_blank' href='index.php?do=show&formid=64&p0={$link_dat2}&p1={$link_dat3}'><b style='color:#aa0000;'>" 
            . OutNF($w_n_s_pl[$key], $w_nf_s_pl[$key], $w_f_s_pl[$key]) . "</b></a></td>\n";
    }
}

// Query user
$userQuery = "SELECT * FROM user WHERE id = '{$id_polzot}'";
$user = mysqli_query($connect, $userQuery) or die("e_1110");

// Check for word match
if (mb_strpos($word, $s) !== false || mb_strpos($word, $s1) !== false) {
    $good[] = $s1;
}
Changes and improvements:
1. Simplified initializations:
Merged variable initialization where possible.
2. Switched from for loop to foreach: This improves readability and eliminates the need to manually track the index.
3. Replaced magic numbers: Used more descriptive variable names where necessary (e.g., $key construction).
4. Handled undefined array keys: Added null coalescing (??) for array elements to avoid notices when the key does not exist.
5. Condensed conditions: Removed duplicate conditions in the if statements, simplifying them.
6. Escaped HTML output: Made sure the output is clear and well-structured.

Абсолютно нормальный код. Можно работать и закрывать тикеты.

Була така сама штука. Майже один в один.
Поставив ларавел, старий код засунув в папку паблік. І старі маршрути смикались звідти.
І, коли треба було щось поміняти, переписував на ларавел, в старому коді вимикав.
За рік майже все переписав.

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

ви б здивувались, скільки насправді навколо людей з поганим знанням англійської думають шо вони кулхацкери і заради економії і через незнання народжують неймінг
inizlznVrbl
cantactDat
anRzt (analyzeResult)
і так далі.

а це кулхацкери десь рiвня trainee?

нажаль ні. Є і рівня солюшн архітект.

Скоріше за усе ти до нього не повернешся ніколи, більше того, не факт, що зміни потрібні саме тут. Ну а 20 років тому так і писали, окрім форматування.

Ні, вже тоді були і темплейт-системи, і фреймворки, і навіть якісь зачатки ORM. Навіть форматування було канонічним — табами...

PHP 5 з підтримкою ООП це 2004 рік, а ще додайте час, щоб ці ORM з’явилися...
Форматування табами я не пам’ятаю, кожен форматував як хочеться.
Тому у когось воно усе воно було самописним. У когось не було, але все якось ладналося.

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

А це ви часом не зібралися якийсь автогенерований чи мініфікований код переписувати? (Який при білді перепишеться тим самим). Може то якась CMS генерує таке?

Ну... виглядає як PHP 20-річної давнини, з яким працювали ще у Far з colorer без жодної IDE. Але код, який працює 20 років та +/- підтримується, то він не самий поганий. Це не виглядає сильно складним, це скоріше неакуратно, і тут більше відсутність мотивації: тобі просто не хочеться цим займатися.

Таке враження, що IDE автоматично покращує якість коду...

к Физерсу рекомендую также Мартина Фаулера Рефакторинг, Кента Бека про ТДД можно, дядя Боб отлично объясняет архитектуру и принциы построения кода и почему так лучше.

А нащо?

Годно хіба скласти все це в мішок і в’¨бати по щам начальству перед пунктом

Настоять перед начальством

Можна ще ногою двері відкрити, один чорт рілі з таким кодом

А я не рекомендую — в первую очередь «дядю Боба» и его инфоцыганщину. Ни к Физерсу, ни отдельно. По качественным дизайну и архитектуре есть масса других более адекватных источников.
И TDD к обкладыванию тестами уже готового кода, к счастью, не имеет отношения.

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

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

Це прям формхуякхуяк якийсь, чи сіречь таблицьтаблицьхуяк

а цей трешак ваще нижче достоїнства навіть звання формшльопа

Тут безумовно. Навіть просте переформатування вже краще, а якщо дати нормальні назви змінним, то можна вже буде з мінімумом коментарів розібратись, що воно робить.

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

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

з ДБФ на СКЛ то є жесть, я такий проект отримав у 2000р, там чувак навіть ораклові констрейнти не використовував, свої понаписав... а яка там була структура даних! скрізний лічильник усіх таблиць!
але я не збіг, :) переписали на 100% те лайно

Що ви робите у такому разі? Чи потрібно звільнятися? Як виправляєте такий код?

1 Бігаю по форумах та питаю порад!!!
2 Потрібно негайно — не для поганого коду мамка тебе на світ народила!
3 Дивись відповідь у п2

Буває, навіть, десь виправив — в іншому місці зламалося.

Быть внимательным и смотреть во все места.

Що ви робите у такому разі?

Абсолютно тоже самое, когда код хороший. Закрываю таски.

Як виправляєте такий код?

Никак. Если нет задачи исправлять такой код, то ничего и не нужно исправлять.

Никак. Если нет задачи исправлять такой код, то ничего и не нужно исправлять.

Имел ввиду не переписывать а что если нужно что то пофиксить читать такой код мало приятно

Тебя подводит отношение к коду. Не существует хорошего или плохого кода. Никто до сих пор не знает что это такое. Ты когда нибудь разбирал код виртуальной машины обфускатора? Это месяцы сидения с тетрадкой и поиском закономерностей, когда у тебя даже нет понимания изначально какой тулзовиной была произведена обфускация и виртуализация.
Мужик, просто бери тикеты в работу и б***ь работай. Когда за***лся, устал, закончился рабочий день — иди домой.

Не существует хорошего или плохого кода. Никто до сих пор не знает что это такое.

Неправда. Граница нечёткая, но крайние случаи очень легко опознаются.

Ты когда нибудь разбирал код виртуальной машины обфускатора? Это месяцы сидения с тетрадкой и поиском закономерностей, когда у тебя даже нет понимания изначально какой тулзовиной была произведена обфускация и виртуализация.

А какое это имеет отношение к вопросу о плохом коде, когда он представлен в исходниках и был написан обычными руками?

Мужик, просто бери тикеты в работу и б***ь работай. Когда за***лся, устал, закончился рабочий день — иди домой.

То есть на работу с таким проектом можно не приходить. Спасибо за разрешение, обязательно передам при случае...

Ты когда нибудь разбирал код виртуальной машины обфускатора? Это месяцы сидения с тетрадкой и поиском закономерностей, когда у тебя даже нет понимания изначально какой тулзовиной была произведена обфускация и виртуализация.

Нейросеть достаточно легко взламывает обфусцированный код даже если и не известно какая именно тулза использовалась для обфускации. Можете проверить. Обфускаторы существовали для людей тогда, когда ещё нейросетки не были широко распространены.

Это было сильно до чатгпг.
Edit. Стоп. Обфускация это не проблема и до чатгпт. Проблема это виртуализация кода на плюсах.

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

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