Як подолати програмування за збігом обставин? [зачинено]


24

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

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

Початкові зонди солдата для мін нічого не виявили, але це було просто щастило. Його привели до помилкового висновку - з катастрофічними результатами.

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

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

Редагувати:

резюме з ваших публікацій:

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

До речі, відповідь важко прийняти, це дуже важко. Усі відповіді справді чудові :)


6
Це допомогло б людям, які, можливо, довго не читали книгу, мати таке посилання, як pragprog.com/the-pragmatic-programmer/extracts/coincidence .
btilly

Якщо у вас дуже коротка кар'єра програмування (або ви не є чоловік-магазин), ви, швидше за все, натрапите на код, який виглядає дивно знайомим, а пізніше піде певний код: копійка падає: він ваш. Це не лише питання з відкритим кодом ...
Роббі Ді

@Robbie Dee. чи можете ви це трохи уточнити? Я не розумію тебе. Дійсно, я маю коротку кар'єру програмування, і це є причиною тегу молодшого програміста.
py_script

2
@py_script Я просто зазначав, що ти можеш настільки ж легко натрапити на твій власний код через кілька років (і бути пошкодженим ним), як чийсь інший. Тож якщо ви почнете з добрих звичок, це виплатить дивіденди пізніше.
Роббі Ді

Відповіді:


26

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

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

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

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

Скоротіть цикл редагування / компілювання / тестування. Якщо ви додасте великий фрагмент коду і погано тестуєте, шанси на те, що він буде вести себе інакше, ніж ви думаєте. Тоді ви "фіксуєте" це якоюсь випадковою зміною, і ви отримали правильну відповідь на даний момент, але не маєте поняття, як це насправді сталося. Ви зараз програмуєте за збігом обставин. Але коли ви додасте 5 рядків і потім тестуєте, шанси на те, що ви отримали правильну відповідь, бо це працює так, як ви думаєте, що це працює набагато краще. Я можу сказати з досвіду, що 5 шматочків по 10 рядків кожен, індивідуально перевірений, - це зовсім інший звір, ніж 50 рядків коду, перевірених всі разом.

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

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


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

1
У мене є багато прикладів. У проекті C ++ я створив класи без методів стратифікації. Після того, як я створив їх, налагодження стало простішим, і розвиток прискорився. У проекті Perl у нас був хеш конфігурації, де кожен розробник мав власну копію кожної нової конфігурації. Додавання параметрів конфігурації було болем, оскільки вам довелося редагувати конфігурацію кожного розробника. Я написав шаблонну систему для хешей, і це стало простіше. У системі звітності я додав функцію показу проміжних результатів. Моя розробка прискорилася, і я навіть отримав звіт про помилку користувачів ...
btilly

1
де фінансовий департамент простежив мою логіку, і знайшов точний запит, щодо якого я пішов не так і яка моя помилка. (Я випадково стискав дублікати рядків UNIONтам, де мені потрібно UNION ALL.) І так далі.
btilly

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

1
@AmyBlankenship Так. Всередині місяця. Іноді смішно всередині, іноді ні. Що я згадав вище, файл конфігураційного файлу є прикладом "іноді ні". Мені пройшло кілька днів, щоб написати, документувати і протестувати нову систему шаблонів. Потім перепишіть існуючий конфігурацію, щоб використовувати його, і бути набагато коротшим, але створити таку ж точну структуру даних. (Це було найважчою частиною проекту.) Отож, дні були марними, абсолютно ніякого видимого результату. Але зусилля окупилися лише за місяць, але з тих пір вони заробляють інтерес.
btilly

41

Він майже зводиться, щоб не здогадуватися . Здебільшого це роблять нові програмісти, але я бачив і ветеранів, тому що вони думають, що це економить час на дослідження. Щось не працює, тож ви додаєте a +1або a -1, змінюєте a trueна falseабо навпаки, впорядковуєте деякі заяви, додаєте або змінюєте затримки, змінюєте пріоритети потоку та інші невеликі перетворення, в основному тестуючи випадкові перестановки, поки це не спрацює.

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

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


1
Відмінний бал +1. Ніде це не застосовується більше, ніж виправлення коду ...
Роббі Ді

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

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

16

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

Не торкайся цього. Це працює. Ми не знаємо, як і чому, але це працює. 1

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

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


1 Щодо контексту, цей коментар з'явився в коді, який обробляє комутатори контексту в примітивній ОС. Код вже був у виробництві кілька років, коли я стикався з ним.


2
це також називається вуду куріння
мінус

1
Навіть якщо кодер вважає, що це правда, такий коментар масово не є корисним. Код цілком може бути складним, але якби ви інакше читали код, ви можете подумати, що він прямолінійний. Усі коментарі - це посилення параної!
Роббі Ді

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

Тож гумова качка не тільки для налагодження. Приємно ... Я думаю, що ми працюємо над однією компанією, у нас є багато подібних коментарів: P
py_script

бувають ситуації, коли виправлення просто працює через глюк в API, і немає кращого та логічного виправлення. Налагодження деяких зібраних сторонніх файлів може пройти так само глибоко, як і налагодження ядра. І навіть якщо ви виявили проблему, після годин налагодження мало що можна зробити. Тож ви по-різному підходите до проблеми. Ви приймаєте модель "чорної скриньки", яка змушує програмувати за збігом обставин. Ви пограєте з дивною поведінкою чорної скриньки, і якщо вам вдасться змусити її працювати так, як вам хочеться, ВЕЛИКИЙ, додайте коментар з "магією не чіпайте" і рухайтеся далі.
Раду Сіміонеску

7

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

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

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

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

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

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


<< Ви повинні навчитися читати код, а не просто писати його. >> Отже, щодо мого початкового питання, чи вважаєте ви, що це допоможе мені додати функції до проектів з відкритим кодом?
py_script

2

Занадто просто кодувати, тестувати та виправляти "на гоночній лінії". У вас є функціонал, який дає X & Y, створює Z. Але що робити, якщо X пошкоджений, а Y недоступний? Що робити, якщо ви не можете вивести Z? Постійно майте на увазі, що може піти не так, і запишіть це на цикл тестів.

Будьте рутини короткими та описовими - найкращий код вимагає декількох (якщо такі є) коментарів.

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

Якщо ви натрапили на кодовий запах, тоді СТОПУЙТЕ. Цей запах навряд чи піде, і трохи зусиль тепер може врятувати вам величезну кількість горя.

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.