Найкращі практики для учасників системи
Вступ
Godot має велику кількість користувачів, які можуть зробити свій внесок, оскільки сам проект орієнтований головним чином на користувачів, які вміють кодувати. З огляду на це, не всі вони мають однаковий рівень досвіду роботи у великих проектах або розробці програмного забезпечення, що може призвести до загальних непорозумінь і поганих практик під час процесу внесення коду до проекту.
Мова
Обсяг цього документа – це перелік найкращих практик, яких слід дотримуватися учасникам, а також створити мову, яку вони можуть використовувати для посилань на типові ситуації, які виникають у процесі подання своїх внесків.
Хоча узагальнений список найкращих практик розробки програмного забезпечення може бути корисним, ми зосередимося на ситуаціях, які найчастіше зустрічаються в нашому проекті.
Внески здебільшого класифікуються як виправлення помилок, покращення або нові функції. Щоб абстрагуватися від цієї ідеї, ми назвемо їх Рішеннями, тому що вони завжди прагнуть вирішити щось, що можна описати як Проблему.
Найкращі практики
№1: Проблема завжди стоїть на першому місці
Багато учасників надзвичайно креативні та просто насолоджуються процесом проектування абстрактних структур даних, створення приємних інтерфейсів користувача або просто люблять програмувати. Як би там не було, вони придумують круті ідеї, які можуть вирішити реальні проблеми, а можуть і ні.
Зазвичай їх називають рішеннями у пошуках проблеми. В ідеальному світі вони не були б шкідливими, але насправді для написання коду потрібен час, він займає простір і потребує обслуговування, коли вже існує. Уникнення додавання чогось непотрібного завжди вважається хорошою практикою в розробці програмного забезпечення.
№2: Щоб вирішити проблему, вона повинна існувати в першу чергу
Це різновид попередньої практики. Додавати щось непотрібне — не дуже гарна ідея, але що є потрібним, а що ні?
Відповідь на це питання полягає в тому, що проблема повинна існувати, перш ніж її можна буде фактично вирішити. Це не повинно бути припущенням чи вірою. Користувач повинен використовувати програмне забезпечення за призначенням, щоб створити те, що йому потрібно. У цьому процесі користувач може наштовхнутися на проблему, яка вимагає вирішення для продовження або для досягнення більшої продуктивності. У цьому випадку потрібне рішення.
Віра в те, що проблеми можуть виникнути в майбутньому і що програмне забезпечення має бути готове до їх вирішення до того моменту, як вони з’являться, називається "Перевірка майбутнього" і характеризується такими напрямками думок, як:
Я думаю, що користувачам було б корисно...
Я думаю, що з часом користувачам доведеться...
Зазвичай це вважається поганою звичкою, оскільки намагання вирішити проблеми, яких насправді не існує в даний час, часто призводять до коду, який буде написаний, але ніколи не використаний, або який значно складніший у використанні та обслуговуванні, ніж це потрібно бути.
#3: Проблема має бути складною або частою
Програмне забезпечення розроблено для вирішення проблем, але ми не можемо очікувати, що воно вирішить кожну проблему, яка існує під сонцем. Як ігровий движок Godot допоможе вам зробити ігри кращими та швидшими, але він не створить для вас цілу гру. Десь треба провести лінію.
Чи варто проблема розв’язувати, залежить від зусиль, які потрібні для її вирішення. Необхідне зусилля залежить від:
Складність проблеми
Частота проблема
Якщо проблема надто складна для вирішення більшістю користувачів, програмне забезпечення має запропонувати для неї готове рішення. Так само, якщо проблему легко вирішити користувачеві, пропонувати таке рішення немає потреби.
Однак винятком є випадки, коли користувач стикається з проблемою досить часто, що необхідність щоразу виконувати просте рішення стає неприємною. У цьому випадку програмне забезпечення має запропонувати рішення для спрощення використання.
Зазвичай легко визначити, чи є проблема складною чи частою, але це може бути важко. Ось чому завжди рекомендується обговорення з іншими розробниками (наступний пункт).
№4: Рішення потрібно обговорити з іншими
Часто користувачі занурюються у власні проекти, коли натрапляють на проблеми. Ці користувачі, природно, намагатимуться вирішити проблему зі своєї точки зору, думаючи лише про власний варіант використання. Як наслідок, запропоновані користувачами рішення не завжди враховують усі випадки використання та часто упереджені до власних вимог користувача.
Для розробників перспектива інша. Вони можуть вважати проблему користувача надто унікальною, щоб виправдати рішення (замість обхідного шляху), або вони можуть запропонувати часткове (зазвичай простіше або нижчого рівня) рішення, яке стосується більш широкого кола відомих проблем, і залишити решту рішення. до користувача.
У будь-якому випадку, перш ніж намагатися зробити внесок, важливо обговорити фактичні проблеми з іншими розробниками або учасниками, щоб можна було досягти кращої згоди щодо реалізації.
Єдиним винятком є випадки, коли область коду має чітко узгодженого власника, який безпосередньо спілкується з користувачами та має найбільше знань для безпосереднього впровадження рішення.
Єдиним випадком є випадки, коли область коду має чітко узгодженого власника, який іноді спілкується з користувачами та має найбільше знань для попереднього впровадження рішення.
№ 5: Для кожної проблеми своє рішення
Для програмістів завжди найприємнішим завданням є пошук найбільш оптимальних рішень проблем. Однак можна переборщити. Іноді учасники намагаються знайти рішення, які вирішать якомога більше проблем.
Ситуація часто стає гіршою, коли для того, щоб зробити це рішення ще більш фантастичним і гнучким, на сцені також з’являються чисто спекулятивні проблеми (як описано в №2).
Основна проблема полягає в тому, що насправді це рідко працює таким чином. У більшості випадків написання індивідуального рішення для кожної проблеми призводить до коду, який стає простішим і зручнішим у супроводі.
Крім того, рішення, спрямовані на індивідуальні проблеми, кращі для користувачів. Цільові рішення дозволяють користувачам знаходити те, що робить саме те, що їм потрібно, без необхідності вивчати більш складну систему, яка знадобиться лише для простих завдань.
Великі та гнучкі рішення також мають додатковий недолік, який полягає в тому, що з часом вони рідко стають достатньо гнучкими для всіх користувачів. Зрештою користувачі вимагають все більше і більше функціональних можливостей, що в кінцевому підсумку робить API і кодову базу все більш і більш складними.
№6: Забезпечте звичайні випадки використання, залиште двері відкритими для рідкісних
Це продовження попереднього пункту, який додатково пояснює, чому саме такому способу мислення та розробки програмного забезпечення віддається перевага.
Як згадувалося раніше (у пункті №2), нам (як людям, які розробляють програмне забезпечення) дуже важко зрозуміти всі майбутні потреби користувачів. Спроба написати дуже гнучкі структури, які одночасно задовольняють багато варіантів використання, часто є помилкою.
Ми можемо придумати щось, на нашу думку, геніальне, але згода виявимо, що користувачі ніколи не скористаються навіть половиною цього або що їм потрібні функції, які не зовсім вписуються в наш початковий дизайн, що змушує нас або викинути це, або зробити ще більш складним.
Питання полягає в тому, як ми розробляємо програмне забезпечення, яке дозволяє користувачам робити те, що ми знаємо, що їм потрібно робити зараз, і дозволяє їм робити те, що ми ще не знаємо, що їм потрібно буде робити в майбутньому?
Відповідь на це запитання полягає в тому, щоб гарантувати, що користувачі все ще можуть робити те, що вони хочуть робити, ми повинні надати їм доступ до низького рівня API, який вони можуть використовувати для досягнення бажаного, навіть якщо це для них більше роботи, оскільки це означає повторне впровадження певної логіки, яка вже існує.
У сценаріях реального життя ці випадки використання будуть щонайбільше рідкісними та незвичайними, тому має сенс написати спеціальне рішення. Ось чому важливо все ще надавати користувачам основні будівельні блоки для цього.
№7: Віддавайте перевагу місцевим рішенням
Коли ви шукаєте вирішення проблеми, будь то впровадження нової функції чи виправлення помилки, інколи найпростішим шляхом є додавання даних або нової функції в основні рівні коду.
Основна проблема тут полягає в тому, що додавання чогось до основних рівнів, що використовуватиметься лише з одного місця на відстані, не лише ускладнить дотримання коду (розділить його на дві частини), але й зробить основний API більшим, складнішим, важче зрозуміти взагалі.
Це погано, тому що читабельність і чистота основних API завжди є надзвичайно важливими, враховуючи, скільки коду покладається на них, і тому що це є ключовим для нових учасників як відправна точка для вивчення кодової бази.
Поширена причина бажання зробити це полягає в тому, що зазвичай потрібно менше коду, щоб просто додати хак у основні шари.
Робити це не рекомендується. Як правило, код рішення має бути ближчим до джерела проблеми, навіть якщо він включає додатковий, дубльований, складніший або менш ефективний код. Може знадобитися більше креативності, але цей шлях завжди рекомендований.
№8: Не використовуйте складні готові рішення для простих проблем
Не кожна проблема має просте рішення, і часто правильним вибором є використання бібліотеки третьої сторони для вирішення проблеми.
Оскільки Godot вимагає доставки на велику кількість платформ, ми не можемо динамічно пов’язувати бібліотеки. Натомість ми об’єднуємо їх у дерево вихідних кодів.
Як наслідок, ми дуже вибагливі до того, що входить, і ми, як правило, надаємо перевагу меншим бібліотекам (нашим улюбленим є бібліотеки з одним заголовком). Ми збираємо щось більше, лише якщо не буде іншого вибору.
Бібліотеки повинні використовувати достатньо дозвільну ліцензію, щоб бути включеною в Godot. Деякі приклади прийнятних ліцензій: Apache 2.0, BSD, MIT, ISC і MPL 2.0. Зокрема, ми не можемо прийняти бібліотеки, ліцензовані згідно з GPL або LGPL, оскільки ці ліцензії фактично забороняють статичне зв’язування у пропрієтарному програмному забезпеченні (яке Godot поширюється, як і в більшості експортованих проектів). Ця вимога також стосується редактора, оскільки ми можемо захотіти запустити його на iOS у довгостроковій перспективі. Оскільки iOS не підтримує динамічне зв’язування, статичне зв’язування є єдиним варіантом на цій платформі.