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


22

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

Я знаю, що існують різні типи документації (у вихідному коді та зовні, діаграмах послідовностей тощо).

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


42
Найкращий спосіб згодом витрачати менше часу на читання коду - це писати більш чіткий і зрозумілий код.
Майл


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

@Laiv Добре з огляду на розробник мого власного коду та, можливо, інший код розробника.
Hamed_gibago

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

Відповіді:


16

Я мушу визнати, що я не згоден з деякими речами, на які рекомендували інші відповіді, тому я збираюся кинути свої два центи;

Коментарі

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

Редагувати : обговорення в розділі коментарів вказало на щось правильно - надмірно коментування зазвичай робиться під час написання поганого коду.

Коментуючи свою роботу має бути точним та мінімальним, але, на мою думку, обов’язково має бути присутнім. Принаймні коментар кожні 15 рядків коду. Наприклад, зверху до блоків коду додайте рядок про те, що ви робите:

def login(username: str, password: str, create_session: bool = True):

    # Filter the user we need from the database
    hash = md5(password)
    users = db.table("users", db_entities.USER)
    results = [x for x in users.query(lambda c: c.get("username") == username and c.get("password_hash") == hash)]


    if len(results) == 0:
        return None, None
    else:
        # Create a login session record in the database.
        if create_session:
            sessions = db.table("sessions", db_entities.SESSION)
            ses = sessions.new()
            ses.set("username", username) \
                .set("expiery", 31536000 + time.time())
            sessions.update(ses)
            return results[0], ses
        else:
            return results[0], None

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

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

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

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

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

# Logging into Gmail when the module is imported
_client = login()
def get_client():
    global _client
    return _client

Приклад уточнення: "Ні лайно, Шерлок. Чи _client = login()увійде в поштову службу? OMG!"

Більше уточнення: login()метод не має відношення до login()методу з наведеного вище прикладу.

Але коментарі, які відповідають стандартам, пояснюють, чому це, а не як, і відповідають на правильні запитання , дуже дуже ( дуже ) корисні.

Вбудовані коментарі

Одне, чого НЕ МОЖЕТЕ робити (і якби я міг би написати це велике, я б це зробив) - це написати свої коментарі в тому ж рядку коду. Це робить коментарі дуже лінійними, що повністю пропускає мету коментувати ваш код.

Наприклад, погані вбудовані коментарі:

outer = MIMEText(details["message"]) # Constructing a new MIMEText object
outer["To"] = details["to"] # Setting message recipient
outer["From"] = "xAI No-Reply" # Setting message sender
outer["Subject"] = details["subject"] # Setting message subject
outer.preamble = "You will not see this in a MIME-aware mail reader.\n" # I don't know what I'm doing here, I copied this from SO.
msg = outer.as_string() # Getting the string of the message
_client = details["client"] # Assigning the client
_client.sendmail(SENDER, details["to"], msg) # Sending the mail

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

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

# Constructing the email object with the values 
# we received from the parameter of send_mail(details)
outer = MIMEText(details["message"])
outer["To"] = details["to"]
outer["From"] = "xAI No-Reply"
outer["Subject"] = details["subject"]
outer.preamble = "You will not see this in a MIME-aware mail reader.\n"
msg = outer.as_string()

# Sending the mail using the global client (obtained using login())
_client = details["client"]
_client.sendmail(SENDER, details["to"], msg)

Набагато чіткіше, правда? Тепер ви також знаєте, що вам потрібно використовувати login()функцію та надавати параметри send_mail()всім, що ви використовували. Допомагає трохи, але одне все одно відсутнє.

Функціональна документація

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

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

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


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

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

2
Цей другий приклад прекрасний.
Гонки легкості з Монікою

7
Коментарі у другому прикладі є занадто багатослівними. Деякі з них (наприклад, "Ми щось знайшли?") Просто повторюють те, що йдеться в коді, і краще їх видалити. Для інших, ви можете отримати більше читабельності шляхом рефакторингу, наприклад, перетворення (stream.is_empty ()) стану циклу або переміщення чека на accept_literals назовні.
Frax

3
@cpburnz: "Мені довелося переглядати занадто багато застарілих проектів та сторонніх бібліотек без коментарів коду, щоб оцінити коментарі, що пояснюють, що відбувається і чому". Точно моя думка весь час: коментарі є для пояснення лайного коду. Оскільки питання полягає в тому, як "як написати код, який легко читати", то явно ця відповідь є неправильною, оскільки фокусується на написанні коментарів для пояснення поганого коду, а не на написанні хорошого коду в першу чергу.
Девід Арно

55

Найкраща документація IMO - це документація, яка вам насправді не потрібна. Я також ненавиджу писати документацію та коментарі.

З цим сказано:

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

19
Ось хороший показник для документації (обов’язкове посилання).
Ніл

4
Це також має бути у списку: поясніть у коді, чому ви робите речі, якими ви займаєтесь.
t3chb0t

2
+1 за останній предмет кулі, оскільки передчасна оптимізація є (в 97% разів) коренем усього зла
gmauch

4
numberOfItemsFoundє досить багатослівним, хоча; занадто багатослівна також проблема.
Матьє М.

6
@MatthieuM., Рідко є "занадто багатослівна" проблема з іменами в коді. Але надто лайливий або загадковий - це дуже поширена проблема.
Девід Арно

25

Ставтесь до свого коду як до документації

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

Про те, як написати читабельний код, написано багато, але деякі ключові моменти:

  • не покладайтеся на коментарі, щоб пояснити поганий код, покращити код і позбутися від коментарів,
  • писати короткі цілеспрямовані функції, методи, заняття тощо,
  • використовувати імена, що відповідають контексту (наприклад, nце добре для циклу, потрібні більш тривалі описові імена для елементів із більшим обсягом),
  • трактуйте назви функцій так, ніби вони були коментарями, наприклад, не використовуйте UpdtTblкоментар, пояснюючи, що він оновлює таблицю з наданими правилами, коли UpdateTableContentsWithSuppliedRulesїх можна використовувати як ім'я,
  • уникати змін. Кожен раз, коли ви змінюєте вміст змінної, ви збільшуєте складність коду. Призначте це нове значення новій змінній (з хорошим ім’ям), де це можливо.
  • нарешті, а головне, уникайте «розумного» коду. Єдиний справжній розумний код - код, який легко читати. Якщо ви пишете якийсь складний біт коду і виявляєте, що думаєте, "вау, я не розумний тут?", Відповідь майже гарантована як "ні, ви ні".

Станьте краще, читаючи код

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

Коментарі - кодовий запах

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

Остерігайтеся автогенерованої документації API

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

Тести теж є документами

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

Малюйте картинки, якщо це допомагає

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

Майте документ "1000 футів"

Нарешті, напишіть собі огляд документа. Що робить додаток? Як це робиться? До яких інших систем він підключається? Такі речі. Не намагайтеся описати тут структуру коду. Нехай код це робить. Нехай цей документ нагадує вам, чому ви написали код в першу чергу.


14
Я погоджуюся з усією вашою думкою, за винятком того, що коментарі мають своє місце. Хоча я погоджуюся, що в коментарях немає сенсу add 1 to i, коментарі повинні пояснювати, чому код робить те, що він робить. Наприклад, код if (!something.Exists()) {...}може використовувати коментар як: // something exists only when (explanation of the broader scenario).
Джонатан

16
Ми всі бачили нашу справедливу частку // increment x x++;коментарів, які не приносять користі, але неправильно викидати дитину разом з водою і заявляти, що коментарі завжди погані. Наприклад, коментарі форми // this case should never happen because xyz throw exception "unreachable".
сердитий праст

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

16
@DavidArno Але ви не можете цього зробити для коментаря, пояснюючи, чому щось не було зроблено. Як //XXX: Not using straight-forward method Foo here because .... Такі коментарі можуть бути надзвичайно цінними, але неможливо передати їх кодом з зрозумілих причин.
cmaster - відновити моніку

7
Мені це подобається ще драматичніше: кожен коментар - це неспроможність добре виразити себе в коді . Наприклад, у мене в одному методі є 4-х рядковий коментар, що пояснює вирішення проблеми сторонніх помилок. Я не зміг це добре висловити в коді, тому це в коментарі . Я б сказав, що це покращує читабельність, тому що я сумніваюся, що комусь сподобається прокручування по горизонталі, щоб прочитати дуже довгу і дуже описову назву методу. "Коментарі - це кодовий запах" - так, але ми маємо пам’ятати, що не все, що пахне, sh * t.
Р. Шмітц

5

Надайте супровідний лист

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

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

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

Прості надзвичайно мінімалістичні моменти:

  1. Вступ, чому цей код (база) існує
  2. Яку функцію виконує підмножина коду
  3. Де знаходиться код (наприклад, назва сценарію)

Приклад

  1. Цей набір сценаріїв викреслює StackOverflow та підтверджує відповіді Деніса Джахеруддіна
  2. а. Цей скрипт відповідає за аналіз html та аналіз того, чи є він правильним користувачем
  3. а. Сценарій можна знайти за адресою: ScrapeAndVote / RecognizeDennis.scr

1

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

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

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

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


1

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

  1. По-перше, написати чистий код; будь-яка інша «документація» подбає про себе після цього. Чистий код - це цілий набір принципів, які слід вивчити в першу чергу: класи з одноосібною відповідальністю, короткі методи, які роблять одне, хороші назви змінних та методів, кращі назви класів / типів, ніж ці , орієнтуючись на метафори (наприклад, викликайте MultiButtSupporter a сода), одиничні тести на позначення вимог, сухий, твердий, послідовна парадигма тощо.
  2. Код розкриває, як працює код; коментарі розкривають, чому код працює. Наприклад, поясніть +1 з "запобіганням помилки на 1", або складною формулою ", отриманою в цьому підручнику чи веб-сторінці".
  3. Що б ви не робили з коментарями, пункт 1 вище цілком може досягти цього в чистому коді. Розгляньте коментарі як невдачі / необхідні зла або навіть брехню, якщо з часом вони не синхронізуються з кодом, коли обидва редагуються. Коментарі не повинні компенсувати погано написаний код, тому що чому коментарі писатимуться з талантом чи обережністю, ніж код?

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


2
Як коментар "запобігає відхиленню від 1 помилки" відрізняється від коментаря, який говорить "+1 - це не помилка друку" або "я не знаю, як вимкнуто одні помилки в моїй програмі"? (Корисні коментарі, як правило, стосуються чогось більшого, ніж +1 у вихідному коді, або до чогось поза вихідним кодом.) Так що все ще залишається "похідне в цьому підручнику чи веб-сторінці" як дійсний і фактично чудовий приклад у вашому пункті №2. Тоді ваш пункт №3, здається, підказує, що ви, можливо, зможете висловити "отримане в цьому підручнику чи веб-сторінці", використовуючи достатньо чистий код без коментарів; Ух, я хотів би бачити це в дії.
Jirka Hanika

@JirkaHanika Можливо, офсайд був поганим прикладом. Щодо 3, я мав на увазі «кожен май», а не «може кожен»; так що ні, я не думаю, що сам по собі код може прояснити такі речі. (Ну, ви можете спробувати gaussianFromThisTextbookNamesApproximation як ім'я змінної, але це погана ідея!)
JG
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.