Ваш код не так понятен, как вы думаете, но есть вещи, которые вы можете сделать, чтобы помочь

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



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

Мой код самодокументируется - Бредовый разработчик

Теоретически код инженера настолько ясен и легко читается, что не требует документации.

Да, это чушь… в основном.

Почему это ерунда «самодокументирующийся код»?

Послушайте, вы могли бы быть Эрнестом Хемингуэем в программировании. Ваш код может быть супер-понятным и легко читаемым (для другого разработчика). Факт остается фактом: это ЕСТЬ код, и какой бы лаконичной и ясной ни казалась ваша работа, он не предназначен для непрограммистов, чтобы получить к нему доступ, не прищурившись и бормоча «что это значит ?!»

Так почему же самодокументированный код - ерунда? Позвольте мне изложить это для вас.

Причина 1: в программировании есть все виды ошибок, которые не документируются самостоятельно.

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

Код написан ДЛЯ машин. Они знают, что с этим делать и почему у нас есть языки программирования. С другой стороны, людям нужен более человечный способ доступа к тому, что делает ваше программное обеспечение.

Читать код и видеть, что он делает, очень далеко от документации. В нем могут быть все элементы того, что делает ваш код, но все ли это самодокументируется? Думаю, все мы знаем, что ответ - «нет».

Взгляните на этот простой объект C #. Я читаю файл, получаю его содержимое и получаю кодировку файла с помощью StreamReader.

var fileContents = “”;
Encoding fileEncoding;
 using (var reader = new StreamReader(filePath, Encoding.Default,  true))
 {
   reader.Peek(); 
   fileEncoding = reader.CurrentEncoding;
   fileContents = reader.ReadToEnd();
 }

Игнорируя тот факт, что что такое StreamReader, может быть непонятно, это достаточно простой код, верно? Итак ... что, черт возьми, с этой строкой?

reader.Peek();

Оказывается, это необходимо для считывателя, если вы хотите получить кодировку файла. А, ну это совсем не самодокументируется, правда? Если бы мы просто потратили еще 10 секунд, чтобы написать это, мы бы сделали код более понятным.

reader.Peek(); //This peek is required to get the file encoding.

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

Причина 2: сложность изначально не самодокументируется

Если вы когда-либо писали файл BASH или BAT, вы знаете, что действия, выполняемые в нем, являются последовательными. Одна задача переходит к следующей. Это похоже на небольшую историю, ведущую от первой строки до последней.

Однако, если вы пишете программу, особенно веб-приложение, такой последовательной истории нет, кроме, возможно, запуска / настройки всех веб-сервисов.

Фактические классы, составляющие современное веб-приложение, не запускаются в последовательном потоке, а вместо этого представляют собой набор веб-контроллеров или контроллеров API, вызываемых, когда клиент вызывает само веб-приложение. Каждый веб-контроллер / контроллер API может иметь потоки, которые порождают новые процессы, отправляют сообщения другим службам, ожидают ответов, чтобы снова запустить веб-перехватчики на слушателях. Ничего из этого не читается ни в каком формате рассказа. Несмотря на весь ваш «самодокументированный» код, новичок или не программист получит от него чувство «я думаю, я понимаю, что он делает». Это опять же не та документация, которой можно доверять.

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

Причина 3: синтаксис кодирования, по сути, нелегко читать

Просто посмотрите на эту функцию jquery, чтобы вызвать конечную точку API.

var myURL="https://some.url/path?access_token=my_token";

$.ajax({
    url: myURL+"&callback=?",
    data: "message="+someOtherData,
    type: 'POST',
    success: function (resp) {
        alert(resp);
    },
    error: function(e) {
        alert('Error: '+e);
    }  
});

Uh…

Я никоим образом не говорю, что с этим синтаксисом что-то не так. Для вызова jquery это вполне приемлемо. Я отмечу, что если вы посмотрите на это с точки зрения начинающего программиста jquery или с точки зрения не разработчика, это может быть и в байт-коде. Это имеет примерно столько же смысла.

Синтаксически языки программирования предназначены для использования ограничений самого языка в сочетании с полезными ярлыками, чтобы ваш код был компактным и легко изменяемым по мере необходимости. Это не должно быть надежным языком в том смысле, что каждый может понять, что происходит. Он предназначен для тех, кто знает этот язык, его синтаксис и сокращения.

Для всех остальных это просто делает ситуацию неясной.

Что ты можешь сделать, чтобы помочь?

Есть вещи, которые вы можете сделать, чтобы помочь не разработчикам с вашим кодом.

Шаг 1. Собственно напишите документацию

Я знаю, святотатство, правда? Пишите документацию ?! Из всех нелепых идей!

Серьезно, никто не просит вас написать «Войну и мир». Но вы можете просто записать основные действия, проверку и обработку ошибок.

  • Клиент вызывает конечную точку API / someurl / object / {id}
  • Контроллер API использует {id} (int) для поиска рассматриваемого объекта в базе данных.
  • Если объект возвращается с нулевым значением, контроллер API возвращает клиенту HTTP-ответ 404 (файл не найден). Контроллер API регистрирует это как предупреждение.
  • Если объект НЕ равен нулю, контроллер API преобразует объект в формат JSON и возвращает его с HTTP-ответом 200 (OK) вызывающей стороне.

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

Шаг 2: сделайте несколько диаграмм

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

Взгляните на websequencediagrams.com, который предлагает простой текстовый формат для создания отличных диаграмм последовательностей.

Текст

title Service one to service two
Service two requester -> Service two http client: Get Contract
Service two http client -> Service one REST API: GET /api/contracts/{123}
Service one REST API -> Service one app logic: get Contract with id 123
Service one app logic -> Service one REST API: Contract
Service one REST API -> Service one REST API: Serialise to JSON / XML / etc.
Service one REST API -> Service two http client: Serialised data
Service two http client -> Service two http client : Deserialise to Contract
Service two http client -> Service two requester: Contract

Полученная диаграмма

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

Шаг 3. Используйте повсеместный язык, чтобы облегчить именование ваших классов и действий

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



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

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

/// <summary>
/// The Customer is responsible for their own login / logout, as well as retrieving their profile information, and management of their
/// settings
/// </summary>
public interface ICustomer
{
     Task<AuthenticationResult> Login(string username, EncryptedString password);
     Task Logout();
     Task<CustomerProfileInformation> GetMyProfile();
     Task SaveMyProfile(CustomerProfileInformation);
     Task<CustomerSettings> GetMySettings();
     Task SaveMySettings(CustomerSettings);
}

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

Шаг 4. Просто добавьте комментарии

Если все это звучит слишком, слишком обременительно, то, по крайней мере, просто добавьте несколько значимых комментариев в свой код. Возможно, они вам не понадобятся прямо сейчас (вы попали в сорняк, поэтому, конечно, код имеет для вас смысл), но в будущем вы вполне можете это сделать.

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

Надеюсь это поможет