Чи варто нехтувати усталеними практиками заради швидкого результату?

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

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

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

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

А ви прихильники перевірених часом практик, як-от чиста або цибулева архітектура, SOLID etc? Чи фраза «Працює? Ну й добре» — це про вас? :)

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось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

не отрицая полезность всех этих практик чистой архитектуры, SOLID и тд, отмечу, что все они были разработаны только для того чтобы снизить когнитивную нагрузку на мозг и нужны тогда, когда работают люди и цена изменений кода очень высока. когда код написан AI, обложен тестами, структурирован удобно для glob и grep, то все равно, насколько он чистый внутри — когда он написан и работает, то этот код даже палкой трогать не будут.

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

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

від усталених хороших практик

Питання про «хороші практики» часто впирається в те, хто визначив їх як «хороші». На моїй пам’яті це більше схоже на моду: спочатку був Греді Буч і RUP, потім час GoF, потім з’явилося XP та Agile, тепер Clean Architecture, SOLID. Це не істини в останній інстанції, а набір евристик, які мають свою ціну.

Особливо серед джунів.

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

А ви прихильники перевірених часом практик

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

Ще маю спостереження, що більшість цих «священних» практик (SOLID тощо) це спроби впорядкувати ООП. В інших парадигмах люди просто пишуть код, який працює, масштабується і не потребує десяти рівнів абстракції для виводу рядка в консоль.

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

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

Особливо у мене є питання до маленьких методів. Код, з яким мені комфортно працювати, від Delphi VCL до Linux Kernel, це до 500 рядків. Дуже маленькі методи створюють ООП-спагетті, проблему відому з часів Smalltalk, коли все зрозуміло, але неможливо знайти де саме реалізована потрібна логіка. Плюс інтерфайсні моменти, то постйно тримати як мікрошматочки коду взаємодіють.

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

я написал общеизвестный объективный факт, а ты частный случай

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

не на все в мире есть исследования, если ты не знал

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

Історія науки буквально завалена трупами, що з’явилися через таку логіку. Експерти десятиліттями вважали лоботомію ліками, а куріння корисним для легень, поки не з’явилися ті самі дослідження, яких «не на все буває».

это не экспертная точка зрения. вот еще один общеизвестный объективный факт: сокращение для слова килограммы — кг. исследований тоже нет. по-твоему похоже тоже не все так однозначно

Щось у вас все змішалось і якась каша. Метод Буча нікуди не дівався, це методика проектувапння ПЗ від збору та формування формалізованих вимог до створення программного коду. Абсолютно переважна кількість команд до 80% за дослідами CMP — Кенрнегні Мелоун на замовлення Пентагону щодо оцінки спроможності підрядниками щодо виконання роботи, не проектує взагалі, розробка йле методом експеремнтального програмування і результати не гарантуються і часто залежать від особистості виконавців.
RUP — тобто Спіраль, це методика управління з компанії Rational яку поглинула IBM, процесс сам по собі вважається гнучким і головною альтернативою Scrum в гнучких методологіях. Нижча розповсюдженість Спіралі здебільшого пов’язана із гіршим маркетингом та великими цінами на навчання. Сертифікати скрам майстрів та тренерів можна було отримати майже всюди, при відносно короткому навчанні і за пормірну ціну. Тренінгові компанії і альянси розгорнули кращій бізнес банально. З ПМ-ами усе як із программістами, є хоороші з вискою кваліфікацією є погані з низькою. Абсолютна переважна кількість колишніх технарів яких свіже призначили, як правило без жодного навчання управління проектами взагалі — денне дно.
SOLID — взагалі набір концептуальних правил, який має сенс дотримутиватись при проектуванні. Той же метод Буча каже вам, що — але не каже як, навідміну від SOLID де усе навпаки.
Паттерни проектування як то GoF та GRASP — набір готових рішень для більшості типових проблем. Command (Action,Event), Controller, Transaction, Chain of Responcibility, Mediator (Handler, Listener, Callback), Producer-Consumer, Multiple readers single writer і т.д. — це усе патерни проектування. Використовуючи фреймверк типу Nest.JS, Spring або QT, ви можете справді і не знати, що то щось зроблено за шаблоном і воно вам і не треба може бути.

Питання про «хороші практики» часто впирається в те, хто визначив їх як «хороші»

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

Джуни найбільші фанати нових течій та карго-культів

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

Далі, GoF, SOLID, GRASP (останній пункт ви не згадували, але все ж) чудово доповнюють одне одного і в дуже багатьох місцях пересікаються між собою. Agile до програмування не має відношення. Clean Architecture точно не є модним, бо це точно не для кожного проєкту, та і не стоїть в одному ряду з SOLID і т.д. бо це вже підхід набагато вищого порядку і є чітко визначеним, коли раніше вказані абривіатури насправді досить абстрактні і досить вільні для реалізації та інтерпретації.

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

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

Ще маю спостереження, що більшість цих «священних» практик (SOLID тощо) це спроби впорядкувати ООП. В інших парадигмах люди просто пишуть код, який працює, масштабується і не потребує десяти рівнів абстракції для виводу рядка в консоль.

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

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

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

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

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

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

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

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

Найкраща архітектура це та, яку легко змінити, а не та, яку ви намагалися зробити «вічною».

Це які такі парадигми де поні і райдуги? Тільки не кажіть про Haskell і інше чисто функціональне непотребство

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

Haskell тут чудовий приклад зворотного. Відносно невелика спільнота змогла створити Cabal та екосистему з неймовірно високою якістю бібліотек. Окрім Haskell та FP є Go, чистий Сі, або навіть Rust чи Zig. Там люди просто пишуть код, який вирішує задачу. Коли архітектура локально оптимальна, вам не потрібні громіздкі патерни, щоб тримати систему в купі.

Для мене популярність ≠ об’єктивна оцінка.

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

Мені дуже цікаво почути яким чином SOLID погіршує вам код.

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

Я не кажу закопуватися у щось складне по типу Clean Architecture, DDD чи CQRS ES, я мав на увазі базові хороші речі по типу:
1. Розділення транспорту, бізнес логіки і доступу до бази даних.
2. Різні типи для цих шарів, або хоча б окремі типи для БД.
3. Шар доступу до БД через інтерфейс
4. Взаємодія з third party через врапери/адаптери, а не напряму
5. Грамотне розділення зон відповідальності між модулями застосунку
6. Нормально налаштований логер, валідація, хендлінг помилок
7. Клін код практики.

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

Найкраща архітектура це та, яку легко змінити, а не та, яку ви намагалися зробити «вічною».

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

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

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

Haskell тут чудовий приклад зворотного. Відносно невелика спільнота змогла створити Cabal та екосистему з неймовірно високою якістю бібліотек.

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

є Go

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

чистий Сі

Хах, да да, у C люди не думають, про патерни просто думають про те яку імплементацію Map обрати для задачі і не зловити sigfault, рейс кондішен і т.д. ))

Rust чи Zig

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

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

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

Для мене популярність ≠ об’єктивна оцінка.

Я з вами погоджуюся, але для чистого FP тут це є обʼєктивним, хочете писати пет проєкти з цим і щоб вам рукоплескала спільнота ентузіастів, що робить витрачає свій час на це саме, будь ласка. Хочете писати ПЗ яким користуються багато реальних людей? Велкам ту SOLID, GRASP, GoF, мультипарадигму

Я не кажу закопуватися у щось складне по типу Clean Architecture, DDD чи CQRS ES, я мав на увазі базові хороші речі по типу:
1. Розділення транспорту, бізнес логіки і доступу до бази даних.
2. Різні типи для цих шарів, або хоча б окремі типи для БД.
3. Шар доступу до БД через інтерфейс
4. Взаємодія з third party через врапери/адаптери, а не напряму
5. Грамотне розділення зон відповідальності між модулями застосунку
6. Нормально налаштований логер, валідація, хендлінг помилок
7. Клін код практики.

Це не абсолютне добро, диявол в деталях.

Найкомфортніше мені було працювати з БД у Delphi, яка прямо порушувала перші пункти вашого списку. І працювати з компонентами прямого доступу до Oracle чи MySQL було значно ефективніше та приємніше, ніж через ADO. Бо зайвий рівень абстракції лише зрізав можливості конкретної бази.

Щодо third-party, то часто адаптер або не дозволяє використовувати лібу на 100%, або ви все одно нікуди з неї не перелізете через специфіку її роботи. Те саме, що я казав про DOA.

Про «грамотне розділення зон відповідальності»: ніхто не сперечається, що складність треба розподіляти. Питання завжди в тому як саме? Грамотно, зрозумів, але трохи неконструктивно.

Щодо логерів, то можна просто видавати в syslog, а далі сисадмін налаштує все, що треба. Для когось це «нормально»...

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

Щодо Haskell то проектів менше просто бо спільнота менша. Але при цьому можливості Cabal/Stack цілком порівнянні з pip а якість пакетів часто в рази краща. І є складні проекти які роками працюють під великим навантаженням. Мала кількість не означає непридатність. А порівнювати можна лише коли дві команди реалізують один й той же проєкт.

Хах, да да, у C люди не думають, про патерни просто думають про те яку імплементацію Map обрати для задачі і не зловити sigfault, рейс кондішен і т.д. ))

В Сі стандартного Map немає. Це взагалі антипатерн для системного програмування. Якщо він і потрібен для зовнішніх даних, то хеш або купа пишуться під конкретну задачу за пару годин. Головні патерни в С це двозв’язні списки та інтрузивні структури даних. Є певні стратегії, але до них не ставляться як до паттернів.

у Rust свої нюанси коли пишеш на ньому і він далеко не ідеальний, і це адекватна мультипарадигменна мова

А що там мультипарадигменного? Це імперативна мова на базі ADT з трейтами. Головна парадигма це Borrow Checker. Я би сказав що це унікальна монопарадигменна мова яка точно ніяк не пов’язана з ООП.

ви з Haskell навіть в один ряд її не ставте

А чому? ADT в Rust це кастрований GADT з Haskell. Трейти це кастровані тайп класи. В Rust все спрощено і обмежено

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

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

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

і ... знову не запускається... капець...

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

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

Та давайте сразу с примеров — есть готовый код и нада добавить одну проверку — есть ли продукт на складе. Есть хелпер который резервирует товар для покупателя. Запускается куча проверок типа есть ли скидки, есть ли куки, и в том числе есть ли товар на складе но она где то на 3и уровня ниже и ее результат тяжело оттуда достать потому она мапится на true/false в функции canWeShip(). И типа хрен поймешь почему не может — толи выходной сегодня, толи баланса нет, толи товара нет. Мое решение — так как stockManager доступен в коде то просто добавить еще один вызов isStockAvailable() если canWeShip() сказало что не можем. После этого добавляем один юнит тест и один интеграционный тест для енд-енд. Готово. Что в реалности, мне пишут коммент — мы типа проверяем два раза есть ли сток, по идее это можна оптимизировать. Как насчет того что бы добавить enum в canWeShip() который будет возвращать true/false/no_stock. Вроде все верно, да ? Во что выливается добавление енума — должны быть поменяны все юнит тесты для canWeShip(), ведь он теперь enum, должны быть поменяны юнит тесты для нижних уровней потому что раньше они мапились на просто на true/false а теперь они мапятся теперь на enum, должны быть добавлены новые тесты — ведь теперю на просто true/false. Должа быть поменяна логика на текущем уровне потому что тут тоже теперь enum, должна быть поменяна документация для паблик методов. Плюс — во время изменения одного из нижних уровней я допустил ошибку и потратил еще два часа что бы найти где одна и пофиксить ее. Потом еще два дня шло код ревью потому вместо 20 строчек было поменяно 300 строчек и ревьюверы нашли что покоментировать. В итоге вместо 1 часа потрачено 2 дня.

Коллеги вам предложили Chain of Responcibility en.wikipedia.org/...​of-responsibility_pattern

В итоге вместо 1 часа потрачено 2 дня.

Здравый смысл никто не отменял, если там единичная история можно было не рефакторить, если регулярно нужно что то удалять и что то добавлять — а куда деваться ?

мы типа проверяем два раза есть ли сток

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

Потом еще два дня шло код ревью

300 строк плевые изменения, на пару скринов от силы. Реально сложно проревьювить от 2000 строк кода больше на мой взгляд, когда там на неделю работы и ревьювить до часа. То что ревьювили 2 дня, вообше проблема не в коде, а в коммуникации. Как и очень большие задачи, но без них бывает не обойтись.

The architecture that actually predominates in practice is the BIG BALL OF MUD.

A BIG BALL OF MUD is haphazardly structured, sprawling, sloppy, duct-tape and bailing wire, spaghetti code jungle. We’ve all seen them. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.

А так да никакому менеджменту и бизнесу не нравится что разработка отнимает время т.е. и деньги, как и в случае со стройкой например. Однако совсем уже не поддерживаемый софт как правило стоит еще больше, как и здание которое или сразу развалилось или требует сразу же очень дорого ремонта и доработок аля Пизанская башня, или вообще придется сносить. А то совсем плохо может быть и пострадали люди если пожар например.
Количество костылей так или иначе доходит до критической массы, после чего уже отладка превращается в кошмар и все сроки летят ко всем чертям. В итоге всеравно не получается вожделенного быстрого и дешево Time To Market, а получается горящий или вообще безнадежный проект, ссоры в коллективе и между стекхолдерами и т.д.
В общем все давно уже известно в индустрии и много раз проедено, написаны книги целые горы книг. Придуманы типовые решения — паттерны, GoF, GRASP. Принцыпы KISS, DRY, YAGNI, BDUF, SOLID, APO т.д. И все равно — 80% индустрии, как херачела на СMM рівні 1 — хаос, так і досі тут en.wikipedia.org/...​Capability_Maturity_Model

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

Як на мене ШІ підвищів структурну якість коду для більшості однотипних задач типу CRUD — однозначно.
Звісно за ним слідкувати треба та і промпт можна задати не вірно, тобто ШІ сам по собі від людського фактору не рятує повністю. Але рутину вирішує 100% і інколи примітивні помилки відсікає.
Виробничість праці ІТ команд незадовільна вже давно, це факт. Потреби бізнесу в червоному океані конкуренції потребують комплексного рішення зокрема інструментів підвищення рівня абстракцій. За великим рахунком без ШІ ми на тому самому рівні, що FORTRAN — але далеко не усі підготовлені як інженери NASA, що писали NASTRAN, а складність інтерфейсів і можливості обладнання кратно збільшились.

Чи фраза «Працює? Ну й добре» — це про вас?

Це про всю айтішку. Просто треба заглянути в сорци будь-якої базової технології, там лінукс, фрібсд, компілятори, в кишки V8, в кубернетеси і взагалом віртуалізацію. Там вашими бест практісес і не пахне. Бест практісес то для операторів фреймворків.

Че ? OpenSSL — тут звісно тяжка правда, як і колись FireFox що був Netscape Navigator до того і став відкритим, там правда проблеми були пов’язані з насліддям до С++ 98 навіть та до С99. Та Linux, GCC та LLVM/Clang, FreeBSD і т.д. це зразки підтримуванності.

GCC компілятори не сумісні між собою. Бінарник С89 з gcc зразка 14 року і бінарник С89 25 року, це два різні бінарника, я не знаю що там підтримують ці наркомани, але про сумістність з попередніми версіями вони ігнорують, а через це і в лінуксі немає обратки.

Так ABI змінили не дивлячись на матюки Лінуса Торвальдса цього не робити gcc.gnu.org/...​ /manual/manual/abi.html
Сам компілятор там нідочого.
Все документовано для зворотної сумісності можна задати ключі

GCC 3.4, GCC 4.x: -fabi-version=2 (Incompatible with previous)
GCC 5 and higher: -fabi-version=0 (See GCC manual for meaning)

Є купа причин як міняти ABI бо міняється залізо, так є і купа причин не міняти його — через зворотну сумісність. У MS VС++ ще гірша проблема із redistributable packagе маніфестами і т.д. Яку вони вирішували за допомогою universal CRT.
Gentoo Lunix пішли в підхід коли усі пакети в похідних кодах і збираються під конкретний сет користувача із -mtune=native. Щоправда є тепер гібридний підхід коли критичні компоненти білдяться з сорців, а різне завантажується в бінарному вигляді предбілжене під «усереднений процесор» так само як у Fedora чи Debian.

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

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

Та на здоров’я.
Чим більше хуйових систем буде написано зараз через аі агенти — тим більше в майбутньому буде роботи по створенню нормальних систем їм на заміну.

бла бла бла, ничего там не будет

Там не буде — це де не буде? Там де розмовляють болгарською?

Всі ми заручники обмежень грошей, часу і якості які ставлять нам замовники — що в сервісних компаніях, що в продуктових. Світ прискорюється, час стає все більш безкомпромісним ресурсом.
Коли почав працювати в індустрії за гроші в 2012, мене мало шо цікавило окрім «красивого, правильного» коду.
Ставши тім-лідом, мене значно більше стало цікавити, щоб було зроблено згідно вимогам; на code review дивився переважно на інтерфейси і дуже поверхнево — на реалізацію.
Зараз же на поточному проекті замість написання коду ми обрали low code платформу, бо хотіли швидко й дешево. Жаліємось звісно, вигрібаємо купу багів але швидкість реалізації приголомшує.
LLM змінили правила гри — тепер можна детально описати підхід до реалізації з врахуванням всіх бажаних практик. Працює добре, гріх не користуватись.
Всі мої практики зводяться до «зробити зараз так, щоб новий функціонал і модифікації забирали в мене мінімум часу на горизонті 3 років і щоб мені не було огидно».

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

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

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

Якщо вам ви думаєте, що гарна програмна архітектура це дорого — спробуйте погану архітуктуру.
Брайян Футе, Джозеф Йодер
Цитата з культової статті Big Ball of Mud (Великий комок бруду). 1999 часи міняються, але бізнес в ІТ — ні. Фредерік Брукс пройшовся по цьому ще 50 років тому, там пів Міфічної людино-години розібрали на цитати.

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

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

Це просто знову спроба пропихнути вайбкодінг в справжні практики і трохи подовжити життя АІ баблу.

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

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

Да ну — наприклад повноцінний TDD де тести написані до коду, без ШІ — муторна штука, при усіх інших там роботи по тестам може бути більше ніж по коду бо їх усе доведеться переписувати.
Докінця пропрацьованих і формалізованих вимог до ПЗ ніколи не буває, саме тому так популярні гнучкі методики Agile — які надають можливість давати корективи раз на ітерацію і реагувати на досвід експерементальної або реальної експлуатації, коли софт вже в підтримці.
А от при використанні ШІ — він може накидати варіантів на перед, з котрих можна просто відкинути не валідне чи додати валідне. І далі написати вже код під створені тести.
Як на мене явний плюс ШІ — це загальне підвищення якості створеного коду, щонайменше на low level рівні.

Да ну — наприклад повноцінний TDD де тести написані до коду, без ШІ — муторна штука, при усіх інших там роботи по тестам може бути більше ніж по коду бо їх усе доведеться переписувати.

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

З мого досвіду, люди сильно перебільшують, що гарні практики значно уповільнюють роботу тим більше в епоху LLM агентів. До того ж використання гарних практик значно спрощує життя у майбутньому і уберігає від рефакторингу, переписування, техборгу і т.д. Тому на мою думку краще витратити на 10-20% часу більше для впровадження тих самих практик щоб зробити все якісно з самого початку, щоб мати набагато більше профіту в майбутньому

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

Такое расскажет любой работодатель. Никто же не скажет что у нас тут одни джуны и постоянные бесплатные сверхурочные, кстати менторинг джуниоров сам по себе разумеется и не оплачивается никак. Джуны на твою непосредсвенную замену, не повышать же тебе зарплату и в должности посто так, тут больше бизнес должен быть и непосредсвенный интерес собсвенника.
На деле, самые вкусные проекты — где ты сам себе хозяин и хорошая прибыль и это в первую очередь. Синий океан конкуренции потому что. Даже допустим гомнокодище от индусов и фреймверк времен царя гороха, но тебе дают рефакторить в разумных приделах — ну есть чем занятся и получать за это деньги. Все при деле все довольны и заказчик и ты. Только тут огромные риски выпасть на мороз со сменой системы. В прибыльном типе бизнеса всегда растет конкуренция, Адам Смит Давид Рикардо вывели этот економический закон. Спрос — рождает предложение.
А когда все круто но 3 человека на один тикет, будет грызня и драка. А в итоге приведут человека от собсвенника и назначат над всеми начальником.

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

It depends 😌. Чуйка має бути, коли це добре, коли ризиково, а коли взагалі не можна.

Чуйка == досвід.

АІ == відстуність досвіду. Це інструмент, використання якого деградує досвід яки вайбкодер недоотримав.

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

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

а в чем плюс если оно даже не работает?)

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