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


156

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

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

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

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


9
настійно рекомендую книги: "Посібник з виживання програмного забезпечення" Стіва МакКоннелла, "Швидкий розвиток" Стіва МакКоннелла, "Рефакторинг" Мартіна Фаулера
Імран Омар Бухш

15
... та «Чистий код» дядька Боба;) (Роберт К. Мартін)
Гендальф

34
Хіба це саме питання не те, що породило багато десятиліть важкого читання та цілі курси в університетах?
декрет

17
@Eric Yin - Я не згоден у коментарях. Для мене це кодовий запах, і в довгостроковій перспективі проекти, як правило, приносять більше шкоди, ніж користі, оскільки вони неминуче застаріють і стають в оману.
JohnFx

8
@Eric Yin: прагнути до самодокументування коду. Використовуйте коментарі про наміри лише там, де вони покращують розуміння.
Мітч Пшеничний

Відповіді:


138

Єдине справжнє рішення, щоб уникнути гниття коду, - це добре кодувати!

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

Звичайні добрі практики можуть допомогти:

  1. Не ускладнювати.
  2. Не ускладнювати. Особливо це стосується архітектури, "великої картини". Якщо розробники , які мають важкий час , щоб отримати загальну картину, вони будуть закоді- проти нього. Тому зробіть архітектуру простою, щоб усі розробники отримали її. Якщо архітектура повинна бути не простою, тоді розробники повинні бути навчені розуміти цю архітектуру. Якщо вони не інтерналізують його, вони не повинні кодувати його.
  3. Прагнення до низької зв'язку та високої згуртованості . Переконайтесь, що всі в колективі розуміють цю ідею. У проекті, що складається з нещільно зв'язаних, згуртованих частин, якщо частина деталей стає незрозумілим безладом, ви можете просто відключити її та переписати цю частину. Це важче або майже неможливо, якщо муфта щільна.
  4. Будьте послідовними. Яких стандартів слід дотримуватися мало, але будь ласка, дотримуйтесь деяких стандартів. У команді всі повинні дотримуватися однакових стандартів, звичайно. З іншого боку, легко стати занадто прив’язаним до стандартів і забути про інше: будь ласка, розумійте, що хоча стандарти корисні, вони лише невелика частина хорошого коду. Не робіть великої кількості цього.
  5. Огляди коду можуть бути корисними для того, щоб команда працювала послідовно.
  6. Переконайтесь, що всі інструменти - IDE, компілятори, контроль версій, системи збирання, генератори документації, бібліотеки, комп'ютери , стільці , загальне середовище тощо тощо - добре підтримуються, щоб розробникам не довелося витрачати свій час на вторинні проблеми, наприклад як боротьба з конфліктами версій файлу проекту, оновлення Windows, шум і все, що банально, але дратує. Необхідність неодноразово витрачати багато часу на такі нецікаві речі знижує моральний стан, що, принаймні, не покращить якість коду. У великій команді може бути один чи більше хлопців, головна робота яких - підтримка інструментів для розробників.
  7. Приймаючи технологічні рішення, подумайте, що потрібно для переключення технології; які рішення незворотні, а які ні. Дуже ретельно оцінюйте незворотні рішення. Наприклад, якщо ви вирішили написати проект на Java , це досить незворотне рішення. Якщо ви вирішили використовувати якийсь варений бінарний формат для файлів даних, це теж досить незворотне рішення (як тільки код вийшов у світ, і вам доведеться продовжувати підтримувати цей формат). Але кольори графічного інтерфейсу можна легко налаштувати, функції, які спочатку були опущені, можна додати пізніше, тому менше наголошуйте на таких питаннях.

8
Це чудові моменти. Я мушу визнати, що я борюсь із "тримайте це просто". Здається, це означає різні речі для різних людей у ​​різних контекстах, що робить "прості" досить складними (але тоді я маю природну схильність до ускладнення речей).
Крамій

3
Я прекрасно погоджуюся з вашими пунктами, особливо "KIS". Але я бачу тенденцію, що дедалі більше (молодших?) Розробників використовують досить складні структури для опису навіть найпростіших контекстів.
chrmue

10
@chrmue: Дивіться "як писати Factorial на Java" ;-)
Joonas Pulakka

8
Умм і "8. Нехай це буде просто".
Dawood ibn Kareem

7
№6 гідний +10.
Джим Г.

55

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

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

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


3
Дуже важливий момент. Я перейняв застарілу систему, багато класів, багато рядків коду, ніякої документації, одиничних тестів. Після старанного створення одиничних тестів для всіх виправлень та вдосконалень коду, дизайн системи перетворився в більш чистий і підтримуваний стан. І ми маємо «сміливість» переписати значні основні частини (охоплені одиничними тестами).
Сем Голдберг

40

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

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

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


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

4
@chrmue Я думаю, саме так, як ідуть справи, але я все це втомлююся. Багато в чому я хотів би, щоб я знову був молодшим розробником, коли я не був так усвідомлений, наскільки помиляється все навколо мене. Здається, я рано потрапив на кризу середньої кар'єри. Але я блукаю ... рада допомогти.
maple_shaft

1
@Murph Чому б у вас не було керівника всезнаючої команди на етапі технічного обслуговування? Кожен бос, якого я ніколи не очікував, нічим менше від керівництва команди, і коли я був керівником команди, я нічого не очікував від себе.
maple_shaft

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

2
@maple_shaft, ймовірно, я старий бурхливий програміст (-: Але є проблема в тому, що це часто "стиль" реалізації, якого слід дотримуватися глибоко в існуючій кодовій базі - і це може бути чужим як кодеру, так і ведучому (для багатьох з реальних причин)
Мерф

18

Ми можемо зробити кілька речей:

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

Створіть культуру, де всі розробники беруть на себе право архітектури. Усі розробники повинні бути залучені до процесу розробки та підтримки архітектурної цілісності.

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

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

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

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


1
+1, особливо для "створення команди, яка може добре працювати разом і фактично відправляти робочий продукт".
deworde

1
Хороша ідея, щоб одна людина була коренем, відповідальним за архітектуру. Однак у вас є "запах команди", якщо ця відповідальність використовується часто: Команда повинна, природно, приймати загальні висновки, а не покладатися на одну людину, щоб дати відповіді. Чому? Загальні знання про проект завжди поділяються, прикріплення його до однієї людини призведе до більшої проблеми врешті-решт: Лише його погляд задоволений, ефективно зрізаючи крила решти команди. Замість цього найміть найкращих людей і нехай вони працюють разом.
каспер

1
@casper: Так. Ви висловлюєте те, що я мав на увазі, швидше, ніж я.
Крамій

18

У цьому питанні я перейду до кореня:

У моєму поясненні буде використання термінів з Microsoft / .NET , але буде застосовано до будь-якої платформи / інструментарію:

  1. Використовуйте стандарти для іменування, кодування, реєстрації, потоку помилок, потоку процесів - в основному нічого.
  2. Не бійтеся прощатися з членами команди, які не дотримуються стандартів. Деякі розробники просто не можуть працювати в межах визначеного набору стандартів і стануть ворогами п'ятої колони на полі бою, щоб зберегти базу коду чистою
  3. Не бійтеся виділяти членів команди на низьку кваліфікацію для тестування протягом тривалих періодів часу.
  4. Використовуйте кожен інструмент свого арсеналу, щоб уникнути перевірки гнильного коду: це включає спеціальні інструменти, а також попередньо написані одиничні тести, які перевіряють файли збірки, файли проектів, структуру каталогів тощо.
  5. У команді з приблизно 5-8 членів, ваш кращий хлопець буде рефакторинг майже постійно - прибирати безлад, який залишають інші. Навіть якщо ви знайдете найкращих фахівців у цій галузі, у вас все одно буде безлад - це неминуче, але його можна стримувати постійним рефакторингом.
  6. Пишіть одиничні тести та підтримуйте їх - НЕ залежайте від одиничних тестів, щоб зберегти проект чистим, вони не роблять.
  7. Обговоріть усе. Не бійтеся витрачати години на обговорення речей у колективі. Це поширить інформацію та видалить одну з першопричин поганого коду: плутанину щодо технологій, цілей, стандартів тощо.
  8. Будьте дуже обережні з консультантами, які пишуть код: їх код, майже за визначенням, буде справжньою штукою.
  9. Переважно робити огляди як етап процесу перед реєстрацією. Не бійтеся відкатів.
  10. Ніколи не використовуйте принцип відкриття / закриття, якщо тільки на останньому етапі перед випуском: це просто призводить до того, що код гниття не залишає запаху.
  11. Щоразу, коли виникає проблема, знайдіть час, щоб її зрозуміти якнайповніше, перш ніж реалізувати рішення - більшість гнилей коду виходить із впровадження рішення проблем, не повністю зрозумілих.
  12. Використовуйте правильні технології. Вони часто бувають наборами та будуть свіжими: краще залежати від бета-версії рамки, від якої вам забезпечена підтримка в майбутньому, ніж залежати від надзвичайно стабільних, але застарілих рамок, які не підтримуються.
  13. Наймайте найкращих людей.
  14. Відкладіть решту - ви не працюєте в кафе.
  15. Якщо керівництво не найкращі архітектори і вони втручаються у процес прийняття рішень - знайдіть іншу роботу.

1
Тепер, що б ви зробили, якби вам довелося підтримувати та покращувати кошмарний 12-річний додаток VB6 зі 100 формами та класами під час роботи над переписуванням C # у вільний час?
jfrankcarr

7
Не згоден з №3. Тестування не слід розглядати як покарання для непідготовлених. Насправді це слід робити всім розробникам і вважати таким же важливим, як кодування та проектування! Якщо у вас є команда непідготовлений в команді, то відведіть його від команди на деякі тренування !.
NWS

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

1
"Не згоден з №10 - це допомагає з якістю коду, якщо зроблено правильно" Це абсолютно помилково в моєму досвіді роботи: код, заблокований, не може бути відновлений, тобто він залишатиметься у своєму поточному стані до розблокування. Цей стан можна перевірити, що він працює на певному етапі, але на більш пізньому етапі ця перевірка є помилковою позитивною: весь код слід залишити відкритим для рефакторингу до етапу перед остаточним тестом на систему.
каспер

3
@casper: IMHO, принцип відкритого / закритого типу не слід розуміти як "ви не можете змінити джерело", а навпаки, "спроектуйте код так, як він застигне". Переконайтеся, що можна розширити код як необхідний, не вимагаючи змін до нього. Результат є в основному більш в'язко зв'язаним та сильно згуртованим, ніж середній код. Цей принцип також має важливе значення при розробці бібліотеки для використання третіми сторонами, оскільки вони не можуть просто зайти і змінити ваш код, тому вам потрібно його належним чином розширити.
Кевін Кеткарт

12

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

  • Розробіть нову особливість
  • Вирішіть проблему

Значно пришвидшити ваш тестовий перший цикл розробки:

  • Рефакторинг для перетворення модулів коду на мову сценаріїв
  • Використовуйте швидкі хмарні тестові машини

Код Refactor для використання низької муфти (сильно з’єднаних всередині блоків):

  • Простіші (більше) функції (підпрограми)
  • Модулі
  • Об'єкти (і класи або прототипи)
  • Чисті функції (без побічних ефектів)
  • Віддаючи перевагу делегуванню над спадщиною
  • Шари (з API)
  • Колекції невеликих одноцільових програм, які можуть працювати разом

Органічний ріст хороший; великий дизайн спереду поганий.

Майте лідера, який обізнаний із сучасним дизайном. Якщо ні, читайте код проекту, поки не будете обізнані.

Читайте книги про рефакторинг.


1
+1 Гарна перша відповідь, ідеальний спосіб представити себе нам!
янніс

11

Проста відповідь: ви не можете .

Ось чому ви повинні прагнути писати невелике і просте програмне забезпечення. Це не легко.

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

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

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

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


9

Я працюю над кодовою базою для продукту, який постійно розвивається з 1999 року, тому, як ви можете собі уявити, це досить складний на сьогоднішній день. Найбільшим джерелом хакерства в нашій кодовій базі є те, що нам часто доводилося переносити її від ASP Classic до ASP.NET , від ADO до ADO.NET, від поштових розсилок до Ajax , перемикання бібліотек UI, стандартів кодування тощо.

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

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

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

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


8

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

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

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

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

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

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

  • Переконайтесь, що архітектура та особливо шари коду чітко розмежовані та відокремлені - це потенційно дозволить замінити шари коду у міру того, як з'являться нові технології, наприклад, замініть інтерфейс Web Forms на інтерфейс HTML5 jQuery тощо, що може купіть рік або більше доданого довголіття.


7

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

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

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

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

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

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


2
Інша назва того, що ви описуєте, - властивість бути детермінованою
jinglesthula

6

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

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

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


6

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

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

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

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

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

І моя особиста улюблена порада - це більше цитата, хоча я не можу згадати джерело:

"Код, як якщо б людина, яка приходить за вами, - психопат самогубств, який знає, де ви живете"


Я завжди вважав, що коментарі до функцій та класів є корисними, навіть якщо просто забезпечити розділення сегментів коду у місцях функцій та класів, використовуючи підсвічування синтаксису. Я дуже рідко вкладаю коментарі до коду функції, але я пишу рядок для кожного класу та функції, наприклад, /** Gets the available times of a clinic practitioner on a specific date. **/або /** Represents a clinic practitioner. **/.
Нік Бедфорд

5

Один із принципів, про який не згадувалося, але який я вважаю важливим, - це принцип відкритого / закритого типу .

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

Всього мої 2 копійки.


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

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

5
  • Будьте розвідником . Завжди залишайте код чистішим, ніж ви знайшли.

  • Виправити розбиті вікна . Усі ці коментарі "змінюються у версії 2.0", коли ви переглядаєте версію 3.0.

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

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

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

  • Проведіть тиждень, як команда знімає попередження, щоб були помітні реальні проблеми.

  • Переформатуйте весь код на стандарт кодування.

  • Переконайтесь, що ваша система контролю версій прив’язана до вашої програми відстеження помилок. Це означає, що майбутні зміни є приємними та підзвітними, і ви можете розробити ЧОМУ.

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

  • Опублікуйте проектні документи на вікі. Це допомагає інституціоналізувати знання.

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

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

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

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

  • Спробуйте встановити тест деяких старих бітів, які не перевірені. Це допомагає зменшити страх перед змінами.

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


4

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


3

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

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

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


2

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

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

Люди не вводять хакі, тому що їм це подобається; їх змушують обставини.


Вимушені обставинами? Люди вводять хакі, тому що (а) вони не знають краще => потрібен коучинг, (б) вони не бачать більшого малюнка => потрібні спілкування, документація та дисципліна; (в) вони думають, що вони розумніші => це найбільше перешкода для подолання (d) вимушених обставинами => швидкі виправлення виправлені, коли під час тиску, але хтось повинен взяти на себе відповідальність і очистити код згодом. Будь-яка інша "обставина" просто БС . З цього правила є винятки, але найбільш так звані винятки заклинають "ледачий".
JensG

2

Я просто хочу поставити нетехнічне питання та (можливо) прагматичний підхід.

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

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

Або якщо ви просто хочете приручити "проект Франкенштейна", це мої поради:

  • Організуйте та спростіть
  • Скоротіть функції
  • Поставте пріоритетність читабельності над ефективністю (коли це прийнятно, і деякі підвищення ефективності занадто жалюгідні, щоб зберегти)

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

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


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

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

1

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

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

Можна навіть розглянути ті невеликі незалежні бібліотеки між багатьма проектами (підмодулі git - ваш друг).

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

Якщо ви використовуєте C або C ++ і не любите ідею мати багато невеликих .so файлів, ви можете зв'язати всі бібліотеки разом у більший .so файл, або ви також можете статичне посилання. Те саме стосується Java, просто змініть .so на .jar.


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

0

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

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

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

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

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