Как мне документировать мой код за минимальное время проверки? [закрыто]

22

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

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

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

Hamed_gibago
источник
42
Лучший способ тратить меньше времени код для чтения позже, чтобы написать более четкий и более понятный код.
Mael
Документация зависит от цели. Если вы обращаетесь к разработчикам, то комментарии в коде будут весьма полезны. Если вы обращаетесь к аналитикам, диаграммы обзора тоже полезны. Если вы обращаетесь к технически подкованной аудитории, составьте руководство пользователя.
Laiv
@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()Вход в почтовый сервис? О Боже!"

Дополнительные пояснения: 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

ИМО, лучшая документация - это документация, которая вам на самом деле не нужна. Я также ненавижу писать документацию и комментарии.

С этим, как говорится:

  • Выберите читаемые и говорящие имена. Не используйте n, но вместо этого, numberOfItemsFoundнапример.
  • Не стесняйтесь хранить части вычислений в постоянной переменной, а не помещать все в одну строку.
  • Переместите частичные задачи из ветвей в их собственные (встроенные) функции, если вы используете их повторно или родительская функция становится длинной и утомительной для выполнения.
  • Будьте более сложными и оптимизируйте код только для удобства чтения там, где это действительно необходимо.
Марио
источник
19
Вот хороший показатель для документации (обязательная ссылка).
Нил
4
Это также должно быть в списке: объясните в коде, почему вы делаете то, что делаете.
t3chb0t
4
numberOfItemsFoundдовольно многословен, хотя; слишком многословный - тоже проблема.
Матье М.
6
@MatthieuM., Редко бывает "слишком многословной" проблемой с именами в коде. Слишком кратко или загадочно - очень распространенная проблема.
Дэвид Арно,
25

Рассматривайте ваш код как документацию

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

Там много написано о том, как писать читаемый код, но некоторые из ключевых моментов:

  • не полагайтесь на комментарии, чтобы объяснить плохой код, сделать код лучше и избавиться от комментариев,
  • написать короткие целевые функции, методы, классы и т. д.,
  • использовать имена, соответствующие контексту (например, nэто хорошо для цикла, более длинные описательные имена необходимы для элементов с большей областью действия),
  • обрабатывать имена функций, как если бы они были комментариями, например, не использовать UpdtTblс комментариями, объясняющими, что обновляет таблицу с предоставленными правилами, когда UpdateTableContentsWithSuppliedRulesих можно использовать как имя,
  • избегать изменчивости Каждый раз, когда вы изменяете содержимое переменной, вы увеличиваете сложность кода. Присвойте это новое значение новой переменной (с хорошим именем), где это возможно.
  • наконец, и самое главное, избегайте «умного» кода. Единственный настоящий умный код - это код, который легко читать. Если вы пишете какой-то сложный фрагмент кода и обнаруживаете, что думаете «вау, разве я не умный здесь?», Ответ почти гарантированно будет «нет, вы нет».

Стать лучше при чтении кода

Чтение кода, независимо от того, насколько оно простое, является усвоенным навыком. Никто естественно не хорош в чтении кода. Это требует практики; много практики. Так, например, перейдите на Github или что-то еще и прочитайте код библиотек, которые вы используете, а не просто используйте эти библиотеки. Найдите код для чтения и прочитайте его.

Комментарии - это запах кода

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

Остерегайтесь автоматически сгенерированной документации API

Также остерегайтесь автоматически сгенерированной документации API. Если мне придется прибегать к чтению таких документов, это будет потому, что ваш код очень трудно читать. Опять же, сделайте код простым, и я могу прочитать это напрямую.

Тесты тоже документы

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

Нарисуйте картинки, если это поможет

Если вам нравится UML, то непременно найдите себе хороший инструмент и сгенерируйте UML-диаграммы из своего кода. Просто никогда не пытайтесь использовать его для генерации кода. Это не очень хороший инструмент для проектирования, и в результате вы получите ужасный код.

Иметь "1000ft" просмотреть документ

Наконец, напишите себе обзорный документ. Что делает приложение? Как это сделать? К каким другим системам он подключается? Такие вещи. Не пытайтесь описать здесь структуру кода. Пусть код сделает это. Пусть этот документ напомнит вам, почему вы написали код в первую очередь.

Дэвид Арно
источник
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".
angrydust
7
Очень хороший список. Но, как @ Джонатан. Я не согласен с комментариями. Иногда приходится учитывать ошибки в сторонних фреймворках. Хотя это может быть преобразовано в его собственную функцию, все же приятно оставить немного описания, почему требуется обходной путь (номер ошибки или имя ошибки / описание ошибки).
magu_
16
@DavidArno Но вы не можете сделать это для комментария, объясняющего, почему что-то не было сделано. Как //XXX: Not using straight-forward method Foo here because .... Такие комментарии могут быть очень ценными, но их невозможно передать с помощью кода по понятным причинам.
cmaster - восстановить монику
7
Мне нравится еще более драматично: каждый комментарий - это неспособность хорошо выразить себя в коде . Например, у меня есть 4-строчный комментарий в одном методе, объясняющий обходной путь для ошибки стороннего производителя. Я не смог выразить это хорошо в коде, так что это в комментарии . Я бы сказал, что это сильно улучшило читабельность, потому что я сомневаюсь, что кому-то понравится горизонтальная прокрутка для чтения очень длинного и очень описательного имени метода. «Комментарии - это запах кода» - да, но мы должны помнить, что не все, что пахнет, это дерьмо.
Р. Шмитц
5

Предоставить сопроводительное письмо

Если вы не находитесь в очень технической области, большинство вопросов вокруг кода будут касаться не «как», а «почему» или «что».

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

Даже если люди являются техническими специалистами, в сопроводительном письме должно быть указано, где они должны что-то искать.

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

  1. Введение, почему этот код (база) существует
  2. Какую функцию выполняет подмножество кода
  3. Где находится код (например, имя скрипта)

пример

  1. Этот набор сценариев соскребает StackOverflow и upvotes ответы Деннис Jaheruddin
  2. а. Этот скрипт отвечает за синтаксический анализ HTML и анализирует, подходит ли он пользователю
  3. а. Сценарий находится по адресу: ScrapeAndVote / RecognizeDennis.scr
Деннис Джаэруддин
источник
1

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

Поэтому, если мне нужно ввести новый параметр в функцию для реализации определенной функции, то есть один коммит, который ничего не делает, кроме добавления параметра в объявлении, в определении и на всех сайтах вызовов. Затем следующий коммит вводит функциональность, а третий обновляет сайты вызовов, которые используют новую функцию.

Это легко проверить, потому что чисто механические изменения можно быстро просмотреть, а затем убрать с дороги.

Точно так же, если вы переформатируете код, это всегда должно быть отдельным коммитом.

Саймон Рихтер
источник
1

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

  1. Во-первых, напишите чистый код; любая другая «документация» позаботится о себе после этого. Чистый код - это целый набор принципов, которые нужно изучать в первую очередь: классы с одной ответственностью, короткие методы, которые делают одно, хорошие имена переменных и методов, лучшие имена классов / типов, чем те, которые фокусируются на метафорах (например, вызов MultiButtSupporter a сода), модульные тесты для указания требований, СУХОЙ, ТВЕРДЫЙ, последовательной парадигмы и так далее.
  2. Код показывает, как работает код; комментарии показывают, почему код работает. Например, объясните +1 с помощью «предотвращает ошибку на 1» или какой-то сложной формулой с «выведено в этом учебнике или на веб-странице».
  3. Что бы вы ни делали с комментариями, пункт 1 выше вполне может достичь этого в чистом коде. Рассматривайте комментарии как сбои / необходимое зло или даже ложь, если со временем они не синхронизируются с кодом, поскольку оба они редактируются. Комментарии не должны компенсировать плохо написанный код, потому что почему комментарии должны быть написаны с большим талантом или тщательностью, чем код?

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

JG
источник
2
Чем комментарий «предотвращает ошибку 1» отличается от комментария «+1 - это не опечатка» или «Я не знаю об одной ошибке в моей программе»? (Полезные комментарии, как правило, относятся к чему-то большему, чем +1 в исходном коде, или к чему-то вне исходного кода.) Таким образом, это все еще оставляет «полученный в этом учебнике или на веб-странице» в качестве правильного и действительно замечательного примера в вашем пункте №2. Тогда ваш пункт № 3, кажется, предполагает, что вы могли бы выразить «полученные из этого учебника или веб-страницы», используя достаточно чистый код без каких-либо комментариев; вау, я бы хотел увидеть это в действии
Джирка Ханика
@JirkaHanika Может быть, один за другим был плохим примером. Что касается 3, я имел в виду «каждый может», а не «возможно каждый»; так что нет, я не думаю, что один код может прояснить такие вещи. (Ну, вы можете попробовать gaussianFromThisTextbookNamesApproximation в качестве имени переменной, но это плохая идея!)
JG