ЦеНеБлог

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

« Про затемнення Вікіпедії, екс-юей та радіочіпи в головах | | Суржикофобія як форма українофобії »

18 квітня 2012

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

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

Досить. Треба щось робити — або забити на те, що ти програмер, і знайти якесь простіше хоббі, або нарешті змусити себе працювати. Не годувати себе медитаціями в стилі «ти можеш, ти сильний, ти не настільки ледачий» (ти справді ледачий, як і всі люди, якщо ця проблема для тебе є проблемою), не картати себе («О, ти сьогодні дивився в стелю цілий день і цілу ніч, бери й роби, ледащо!»), не морочити собі голову в якийсь інший спосіб. Коротше, треба просто розібратися, щó заважає тобі рухатись, і по можливості усунути цю перешкоду. Методика обходу перешкоди має бути реалістичною. Безглуздо вчити страуса літати, щоб він міг перелетіти через гори, зате варто подумати, як застосувати його біговий скіл, розпланувати маршрут пробігу і т.д.

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

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

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

Індивідуальний стиль загалом вимагає ощадливості. Це очевидно: доки програміст у команді один, зробити він може не більше, ніж один програміст. А отже, чим менше часу він тратить на створення одного й того ж функціоналу, тим краще. З цього випливає, що чим менше коду він пише для одних і тих же дій, тим краще. Геть рутину й схоластику! Код мусить бути компактним — без перевірок на ненадійність у неможливих ситуаціях, без коментарів, що затуляють собою код, зате, можливо, з купою макросів, якщо ваші руки достатньо прямі для їх осмисленого використання, автоматично згенерованими фрагментами і т.д.. Зрозуміло, що й відлагодження при цьому має займати якомога менше часу. Зручно, коли відлагоджувана програма маленька — тому великі проекти варто розбивати на окремі незалежні модулі. Кожну нову функцію можна протестити в спеціально для неї зробленій тестовій програмі, в юніт-тесті чи в інтерактивному середовищі (REPL, IDLE, BeanShell) — кому як зручніше. Кінцева мета всього цього дійства — отримання якомога більшої кількості програм, здатних щось робити, при мінімальних витратах людського ресурсу.

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

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

Декілька слів про REPL. Коли я ще тільки вчився в школі, моєю першою мовою програмування був gw-basic. Звичайно, це стара й примітивна мова (навіть на той час), але позитивним моментом у ньому було те, що для виконання якихось простих обчислень можна було просто ввести команду й одразу отримати результат на екран. Більш продвинуті QBASIC та QuickBASIC також мали таку можливість, що робило їх дещо зручнішими для роботи, ніж Turbo-BASIC з аналогічними рештою можливостей. Після школи до інтерактивних програмних середовищ я повернувся лише недавно, коли заглибився в ліспи. Переконуюсь, що це достатньо зручна й потрібна річ, яка в поєднанні з функціональним чи об'єктно-орієнтованим програмуванням дає ще більше можливостей, ніж у суто алгоритмічному бейсіку. Якщо йдеться про лісп, пітон чи скалу, REPL є дефолтним середовищем роботи програміста. З такими мовами, як джава, С чи РНР, вже складніше: вони не були розраховані на такий режим роботи, інтерактивне середовище не входить у їх комплект, але існують сторонні розробки РЕПЛів для цих мов (наприклад, BeanShell для Java). Головна перевага інтерактивного середовища перед, наприклад, тестовою програмою — економія часу. У добі лише 24 години, з них частина йде на сон, прийом їжі, гігієнічні процедури, роботу (якщо є)... Звичайно, нема нічого складного в тому, щоб кожного разу створювати проект, ретельно оформлювати його початок і кінець, компілювати і т.д., але навіщо? Якщо нас цікавить, як працюватиме пара рядків коду, слід тратити час на цю пару рядків — і не більше.

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

  1. Написання псевдокоду — опис того, що програма робитиме, у вигляді спеціально маркованого коментаря.
  2. Пошук рядків псевдокоду й випадковий (з можливими пріоритетами) вибір кількох з них — робиться машиною
  3. Аналіз знайденого псевдокоду
  4. Деталізація опису, що може включати як псевдокод (але більше одного рядка), так і робочий код (з можливим виправленням та доповненням в інших місцях програми). При цьому коментар, який ми деталізуємо, відмічається як оброблений (я ставлю двокрапку замість трикрапки). Далі — повернення до пункту 2.

Після пари тижнів роботи з цією штукою (яку я назвав AutPlan) я міг сказати: в цьому справді є сенс. Головна причина того, що я до того часу не створив нічого вартого уваги — не маючи над собою ніякого контролю, мені було надто легко закинути роботу на невизначений час. І зовсім інша річ, коли щодня хтось просить зробити десяток-другий елементарних дій, від яких залежить сенс його існування — якось навіть незручно відмовити (навіть якщо цей хтось — програма, яку я сам написав ☺). Протягом перших днів у такому режимі я встиг зробити більше, ніж за попередні півроку. Зокрема, нарешті руки дійшли до активного розгрібання старого недописаного коду, що пилився роками на диску. І, як це не дивно, в якийсь момент у мене з'явилось відчуття додаткового вільного часу: діяльність породжує потребу діяльності. Жаль, що автоплан ще не можна застосувати для інших речей (відкрию секрет: ЦеНеБлог на 90% складається з чорновиків, які я недописав і кинув — забув, відклав до наступного натхнення, засумнівався, чи варто взагалі це писати…) — але рано чи пізно я напишу й цей функціонал, він сам мене змусить себе дописати.

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

Звичайно, запропонована методика має купу недоліків. Зокрема, єдиною програмою, написаною таким способом і при цьому придатною для використання, є лише сама ця програма. Чому? Просто я не можу дозволити собі писати поганий код у ній — тоді програма просто не запуститься. А отже, автоплан — скоріш, засіб для цілеспрямованого вдосконалення робочої програми, а не для написання з нуля (втім, і в «брудному» коді теж є певний сенс). Відчуття ейфорії, пов'язане з будь-якою новою діяльністю, через пару місяців зникло, як і відчуття часової свободи (як гадаєте, чому я так рідко пишу в цей блог?). Срібних куль не існує, на жаль. Хоч і не всі можливості ще було випробовано (наприклад, чом би генератор планів не доповнити перевіркою тестових задач?). Програма, що має здатність удосконалювати себе, використовуючи людину як інструмент, рано чи пізно досягне чогось великого — принаймні, мені б хотілось вірити в це…

P. S. Власне, сама програма в тому вигляді, як вона є сьогодні. Для роботи з нею потрібно встановити Clojure і, бажано, UnxUtils та Notepad++ (чи повикидати зайве з autoplan.bat); лінуксоїдам доведеться написати скрипт для запуску самостійно. Знаю, на іншому комп'ютері без деяких змін програма може й не запуститись — власне, й додаю її не як робочий софт, а як приклад сирого коду, який можна переробити під власні потреби (а далі він переробить вас ☺).

Автор: Python. Опубліковано 18 квітня 2012 21:39
Змінено 01 вересня 2012 3:46
Категорії: Clojure, Програмерство, Філософія