Русский
Русский
English
Статистика
Реклама

Документирование

Хороший, плохой, злой комментарий

03.04.2021 08:20:33 | Автор: admin

Зачем нужны комментарии, правда ли, что хороший код можно прочитать без них и как перфекционизм замедляет разработку в 4 раза. Новичкам, командам, профи.

"Хороший, плохой, злой", 1966 г."Хороший, плохой, злой", 1966 г.

Интуитивное знакомство

с комментариями как и в любых отношениях создаёт скрытые проблемы. Со stackoverflow или от своего творческого начала мы неосознанно формируем манеру комментирования. Кто-то излишне подробную, кто-то с юморком, а кто-то вообще пишет "без комментариев" и через пол года даже не пытается понять, как работает его код.

П.С. Если ты тот человек, который узнал о комментариях в коде из книги, дай знак) Если тебе сразу нужны ответы они в конце.

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

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

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

http://personeltest.ru/aways/shoot-photo.com/desktop-wallpaper-zen.htmlhttps://shoot-photo.com/desktop-wallpaper-zen.html

Совершенный код

это перевод названия книги*. Из 950 страниц осмысленного текста, популярность обрела одна фраза: "хороший код является самодокументированным". А к ней пояснения в виде: "хорошему коду не нужны комментарии", "называй переменные и методы понятно, тогда комментарии не нужны".

Круто быть столь категоричным, а главное просто. Но к чему это приводит? Часть превращает комментарии в искусство, стремится к идеалу, размышляет по 20 минут над названиями. Другая часть формирует чек-листы, правила оформления, требует соблюдения шаблонов. И то, и другое полезно, вот только они забывают о "смысле жизни" комментариев.

Из возможных 20% времени программирования, которые есть у соло-разработчика, в команде остаётся всего 5.

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

В примере выше, 20% времени уделяется программированию и 80% решению того, что и как программировать, изучению контекста, ТЗ. Это бОльшая часть работы по умолчанию. И чем больше проект, тем ближе к 100% можно "страдать" / "ничего не делать" (нужное подчеркнуть). Чтение даже идеального кода == не программирование.

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

Всё остальное лишь форма. Помните о смысле, тогда она будет руслом, а не плотиной из ограничений и бюрократии.

*Code Complete, Стив Макконнелл, 1993. Для сохранения смысла точнее будет перевести как "Завершение кода" или "Завершенный код". Комментарии то, что делает код завершенным, готовым к "эксплуатированию" пользователями, разработчиками, а также обеспечивает комфорт его доработок.

Ответы

П.С. По оформлению кода и комментариев есть много руководств, вместо очередного, здесь тезисы для размышлений.

  1. Существуют разные варианты "использования" кода и комментарии для них отличаются.

    1. Подключение по типу "чёрный ящик" пользователя интересует только что на входе/выходе. Обычно в виде шапки в файле класса и около методов. Хорошо указывать в шапке дату актуализации, перечень методов (содержание). Идеальное использование: за минуту прочитал и пользуешься.

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

    3. Разработка комментарии в коде, короткие, описывающие этапы, группы/блоки операций, а так же комментарии вида TODO (сделать), FIX (исправить) и т.д. Они не дублируют код, а иллюстрируют, как краткое содержание параграфов. В идеале: посмотрел шапку, пробежался по описаниям и нашел нужное место за пару минут работаешь.

  2. Неопределенность и навигация. Можно прочитать 10 000 строк идеального кода, понять его и исправить 3 строчки. Хорошие комментарии те, что позволят сделать это "сразу", а не к обеду. Плюсом будет документирование архитектуры (хотя бы), но это другая история.

  3. Красота единообразие не только красиво, но и понятно. Привычное быстрее воспринимается. Определите удобные для себя правила оформления в команде.

  4. Шаблоны упрощают жизнь, но без фанатизма, у функций бывают необязательные параметры.

  5. Незавершенность буквально. Пока код используется - он не завершен. Не относитесь к нему, как к памятнику, "камню, из которого убрали всё лишнее". Искусственные блоки для кода, лишние строки для визуального отделения, рабочие комментарии, идеи... Всё это может быть, если оно соответствует духу вашей команды.

На этом у меня всё, успехов!

П.С. Буду рад дополнить статью идеями из... комментариев.

Подробнее..

Семь бед один ответ как мы решали проблему постоянных исправлений

11.12.2020 18:19:05 | Автор: admin
Приветствую, Хабр! Меня зовут Павел Воропаев, я Software Engineer в компании Exness. Ранее успел поработать в разных российских компаниях в качестве фулстек разработчика, разработчика баз данных Oracle, Python-разработчика и тимлида. По случаю завершения моего испытательного срока я решил написать статью, в которой бы хотел поговорить о том, как можно оптимизировать процесс погружения в задачу. Я расскажу о накопленном ранее опыте, и о том как мой опыт выручил меня, когда я пришел в Exness. В примерах буду описывать взаимодействие микросервисов с помощью sequence diagram.

image



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

В чем проблема?





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

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

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

Как это можно исправить?



На предыдущих местах работы я встречал такой алгоритм работы:

  • сбор сведений и формирование требований;
  • команда груммит и продумывает общее решение;
  • назначается исполнитель, который реализует задачу;
  • код-ревью;
  • исправления;
  • тестирование;
  • еще исправления;

...

  • еще исправления;
  • долгожданное завершение задачи.


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


Тогда алгоритм работы станет следующим:

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


Почему так важно описать техническое решение до самой реализации:

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


Как я применил этот опыт в Exness?


image

Придя в Exness, мне хотелось побыстрее освоиться в команде, изучить инфраструктуру и начать решать боевые задачи. В первой емкой задаче я решил использовать накопленный опыт и минимизировать риск некорректного решения задачи. Для описания взаимодействия сервисов решил использовать диаграммы последовательности, блок схемы для описания работы алгоритмов и ER-диаграммы для описания схемы БД.
В процессе рисования диаграммы я узнавал от коллег, какие сервисы могут понадобиться для решения моей задачи, проверял запросы к ним и данные в БД, поэтому уже понимал, что и как работает. На разработку диаграммы ушло не много времени, в процессе ревью диаграммы я получил полезный фидбек:

  • фронтенд-разработчик хотел знать, в каких случаях, какие данные и статусы он будет получать от бэка;
  • QA необходимо понимать, откуда берутся данные в сервисе, чтобы покрыть как можно больше кейсов.

На диаграмме я детализировал исключительные ситуации, и как они выходят наружу, а также используемые источники данных. Это дало возможность наглядно показать коллегам, как работает функционал и чего от него ожидать, соответственно, коллеги могли начать реализовывать свои части, не дожидаясь моей реализации. Фронтенд-разработчик знал, как будет отвечать сервис, и мог начать писать интеграции, у QA была информация, как сервис реагирует на разные ситуации и как воспроизвести эти ситуации. В результате, разработка и погружение в задачу получились достаточно быстрыми, а нарисованная диаграмма пополнила документацию разрабатываемого сервиса.

Пример



Ниже описанный пример является собирательным из различных ситуаций.

Новому разработчику прилетела задача с формулировкой "Написать новый микросервис для отклонения просроченных заявок. Уведомить клиентов о смене статуса.".

После выяснения технических деталей понять задачу можно так:

  • собрать микросервис, в нем сделать одну POST метод API с названием reject_old_requests;
  • в этом метод API надо получить данные из БД, в запросе указать фильтры по пользователю, статусу и дате;
  • по каждой заявке сменить статус в сервисе, который управляет заявками;
  • затем отправить запрос в сервис нотификации, чтобы уведомить пользователей об изменении статуса заявки.

Диаграмма последовательности для этой задачи могла бы выглядеть так:



и на какие ошибки можно было бы напороться:

  • под новым микросервисом аналитик мог подразумевать обычный метод API в микросервисе для работы с заявками, но распознать такой сценарий сложно (в моей практике был случай, когда под микросервисом аналитик понимал обычный метод API, насколько мне известно аналитик не адаптировался к верной терминологии);
  • возможно, у заявки есть подзаявки или связанные заявки, о существовании которых новый разработчик может не знать, а аналитик может забыть сообщить и надеяться, что разработчик сам раздобудет информацию;
  • возможно, заявок будет много, а их отклонение в проде будет занимать много времени. В таком случае лучше бы заложиться и сделать возможность отклонять в фоне;
  • хорошая практика получение данных из сервиса, а не из его БД напрямую. Ведь в сервисе, который управляет заявками может быть дополнительная логика выборки.


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

Как бы выглядела диаграмма после исправлений:



Какая польза от диаграмм?



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

Какие выводы можно сделать?



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

Диаграммы однозначно помогут с:

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

Лично в моей практике диаграммы были и остаются незаменимым инструментом.

Желаю и вам найти инструменты, которые будут оптимизировать вашу работу. Спасибо за то, что дочитали до конца.

P.S. Напишите в комментариях, пользуетесь ли вы подобной практикой, какие инструменты вы используете?
Подробнее..

Представление модели предметной области (МПО) и точек интеграции

16.01.2021 14:23:21 | Автор: admin
Как известно, описание архитектуры состоит из множества представлений, для соответствующих точек зрения, интересов и заинтересованных сторон.

В этой статье я расскажу о способе создания представления (диаграммы) модели предметной области (МПО), дополненное связями с точками интеграции, на базе которых построена функциональность системы: хранимыми процедурами, функциями и веб-сервисами. Таким образом, данное представление хорошо подойдёт проектам с большим количество точек интеграциий и поможет разработчикам и аналитикам быстрее ориентироваться в проекте, порой даже не заходя в код.

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

Возможности, которые даёт такое представление:
диаграмма МПО позволяет быстро получить понимание о функциональности, которая существует в системе, какие сущности пристутствуют в системе и какие операции с ними можно выполнять;
связь сущностей МПО с точками интеграции ускоряет поиск нужного участка кода при модификации функционала. Понимая какую операцию и по какому объекту надо модифицировать, можно быстро найти точку интеграции, а отталкиваясь от неё проанализировать весь стек вызова;
удобно накапливать информацию о предметной области в простом наглядном стиле;

Вопросы, на которые отвечает такое представление:
какие сущности МПО существуют в системе?
как сущности МПО друг с другом связаны?
какие действия можно выполнять с сущностями МПО?
с помощью каких точек интеграции выполняются те или иные действия?

Представление сущности МПО



Представление строится на основе диаграммы классов. Для отображения сущности МПО используется класс. Сама сущность МПО представляет из себя абстракцию, которой может не существовать в реализации в описанном виде.

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

Название аттрибута задаётся в наиболее удобной для понимания форме. В случае с аттрибутами чаще всего было проще использовать то название, которое указано в коде.

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

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

Точки интеграции это могут быть хранимые процедуры, функции или веб-сервисы. Описываются по формату %схема/веб-сервис%: хп/хф/метод веб сервиса. Стрелкой сояединяются с соответствующим методом.

image
Рисунок 1. МПО на примере одной сущности

Пример того, как описывается одна сущность МПО изображён на Рисунке 1.

Представление МПО



Итоговое представление МПО может выглядеть примерно как на рисунке. В примере я привёл значительно упрощённую модель. В реальной модели было в 10-15 раз больше сущностей с значительно большим количеством методов и точек интеграции. Однако даже с большими размерами МПО было достаточно просто ориентироваться. Свою роль сыграливозможностям Enterprise Architect и Visual Paradigm, однако в первую очередь помог логический поиск Функциональность->Сущность->Метод->Точка интеграции

image
Рисунок 2. Пример полного представления МПО.

На рисунке 2 изображён пример полного представления МПО. По этому рисунку уже можно сложить мнение о том, какая функциональность реализована в приложении.

Как представление МПО + точки интеграции может упростить разработку



Для наглядности я приложил диаграмму компонентов (Рисунок 3), распределённых по приложениям инфораструктуры проекта:
UIWebSite
MainOnlineBackendService
PCIDSSOnlineBankLogicService

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

image
Рисунок 3. Диаграмма компонентов.

Задача 1:
Допустим, что у нас стоит задача модифицировать функциональность открытия счёта и мы не знакомы с кодом проекта. В такой задаче может прийтись исследовать стэк вызова, а учитывая, что в каждом приложении существует свой набор компонентов, стэк вызова при клике на кнопку Открыть счёт может состоять из 8 уровней:
1 ReactUI
2 RestApiController
3 AccountCachedController
4 AccountServiceWrapper
5 MainOnlineBackendServiceImplementation
6 AccountServiceWrapper
7 OnlineBankLogicServiceImplementation
8 sheme1: sp_createAccount

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

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

Задача 2:
Допустим, что у нас стала возникать ошибка при выполнении какого-либо действия. Для проектов с множеством интеграций частой причиной ошибок является ошибки внешних систем, например было выполнено обновление хранимой процедуры, отключение/недоступность веб-сервиса. На уровне пользователя такие ошибки совсем не очевидны и возникает ощущение, что проблема конкретно в системе, с которой работает пользователь. Чтобы локализовать ошибку чаще всего необходимо проанализировать стэк вызова.

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

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

Задача 3:
Другое множество, где диаграмма была полезна это различные вопросы:
какая внешняя система отвечает за ту или иную функциональность
какая точка интеграции используется для выполнения того или иного действия
где получить номер карты по её Id
кто отвечает за функционаность со стороны другой системы

Задача 4:
Вы исследуете систему и вам необходимо накапливать информацию о всех понятиях и функционале системы. Диаграмма помогает это выполнять в достаточно локаничном виде. В дальнейшем такая декомпозиция/композиция позволяет спроектировать архитектурные слои
Подробнее..

Момент, когда проектная документация нужна

28.12.2020 12:07:24 | Автор: admin
Время идет, планета крутится, системы растут и развиваются, а я продолжаю слышать в кругах аналитиков сожаление: Эх, пришел на проект, а тут никакой документации, смотрим в код.

Но это ерунда. Хуже, когда заказчик говорит: Создали два разработчика. Уволить не могу, хотя почти ничего не делают, только по мелочи донастраивают. А с этой системой у нас уже и бухгалтерия интегрирована, и Документация? Нет ее. А надо?.. Спасите-помогите!

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




Что это за зверь документация?


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

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

Для кого документировать?


Если нет понимания, кому нужна проектная документация, то она не нужна. Возможно, прочитав эту статью чуть дальше, мнение может резко поменяться, но это не точно.



В первую очередь документация нужна команде разработки и заказчику.

Разработчик быстрее осознает, над чем он вообще трудится, спокойнее принимает чужое наследство.

Тестировщик каждый раз не находит одни и те же ошибки, которые на самом деле уже стали особенностями реализации.

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

Иногда проектная документация нужна просто потому, что так сказали.

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

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

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

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

Причины, по которым компании приходят к внедрению документирования


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

Есть сервис МойСклад и 2007 год. Прекрасный пример стартапа от двух разработчиков. Фундамент сервиса был целиком заложен Аскаром (генеральный директор) и Олегом (технических директор). Если почитать историю создания МоегоСклада, то можно узнать интересный факт уже тогда было неосознанное документирование продукта в рабочей тетрадке в клеточку!

Любые знания, зафиксированные на материальном или цифровом носителе, представляют из себя ту самую проектную документацию, которая впоследствии помогает устанавливать причины: почему эта кнопка работает именно так, а не иначе.



На момент, когда у продукта было 0 пользователей, лэндинг и рабочая альфа-версия, документировать было бессмысленно. Да и сейчас любой самостоятельной команде разработчиков, запускающих стартап, уверена, документировать не надо вы сами творите свое сокровище и знаете его. Лучше докрутить еще парочку фич, чем заниматься печатью лишних символов с описанием системы для себя. Время бесценно. А вот тем, кто заказывает разработку стартапа, я советую задуматься, в какой момент они могут пожелать заменить подрядчика и начинать строить свою команду.

Пример с автомастерской


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

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

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



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

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

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

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

И все успешно получится, потому что система обычная, никаких наворотов нет.



Но вот привезли Aston Martin или Ferrari. А я обычный механик в среднестатистической автомастерской. Конечно, сначала я обрадуюсь такому. Но потом, когда дело дойдет до ремонта, я буду вдумчиво смотреть на это чудо света и искать все возможные инструкции, чтобы устранить неисправность.

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

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

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

За 13 лет МойСклад смог очень круто подрасти: веб-приложение для RU- и US-площадок, кассовое ПО для трех платформ, мобильные приложения, шесть протоколов API и много-много всего.

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

Когда я открыла капот дорогого и любимого Aston Martin, я поняла, что взяла очень интересную и сложную машину. Сначала было длительное изучение начинки, а теперь нужно время, чтобы успевать и развивать новое, и описывать ранее созданные детали.

Одна из основных причин начала накопления знаний в МоемСкладе продукт стал большим и сложным.

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

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



Программный код и есть документация


Так говорят разработчики. И нет, это не так.

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

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

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

Как нас много


Как масштаб проекта по части количества людей влияет на необходимость появления документации.











Сервис МойСклад начинался с Аскара и Олега 13 лет назад. Целиком знают продукт всего три человека: Аскар, Олег и Максим присоединившийся к ним немногим позже продакт и бизнес-аналитик.

Сегодня компания насчитывает более 150 человек. Три хранителя знаний на тридцать сотрудников? Возможно. А на команду от ста человек? Да и помнить все детали, особенно когда реализовывал их не ты, просто невозможно. Поэтому нормой стал ответ смотри как на проде.

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

Может ответить только зафиксированное знание, которое либо есть, либо нет, либо оно в человеке (а значит его нет).

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

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

Не храните знания в людях это опасно


Рынок IT-специалистов очень бодр и динамичен. Отсутствие документации на продукт может быть опасным. Человек, уходя из компании, уносит с собой знания о тех частях, которые он делал. Это плохо тем, что развитие и сопровождение неизведанных частей становится очень дорогим удовольствием нужно исследовать, как работает сейчас и достраивать над текущим поведением нечто новое.

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



Сегодня все более актуальна тема с удаленной работой, да и ранее команды разработки всегда обсуждали задачи в чатах (Slack, Telegram, Skype и т.д.).

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

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

Моя позиция такова: стараюсь минимизировать развернутые ответы на вопросы в чатах и максимально ссылаться на существующую документацию:

Разработчик: [Вопрос]
Я: [ссылка на Confluence] п. [название]


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

И про контекст










Итого: где же тот самый момент?


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

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

Что может дать наличие документации на программный продукт?

  • Меньше обсуждений в чатах и поисков причин почему так.
  • Быстрее погружение в контекст.
  • Команде проще понимать и оценивать объем изменений для новых задач.


А такой результат влечет за собой как минимум экономическую выгоду.

Ссылки


analystdays.ru/ru/talk/83497 Analyst Days. Как мы процесс документирования внедряли
habr.com/ru/company/moysklad/blog/452016 Сервис МойСклад 12 лет в облаке (уже 13!)
Подробнее..

Документирование API в Java приложении с помощью Swagger v3

07.01.2021 18:21:18 | Автор: admin

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


Создание документации вручную утомительный процесс. Swagger поможет вам упростить эту работу.


Что такое Swagger?


Swagger автоматически генерирует документацию API в виде json. А проект Springdoc создаст удобный UI для визуализации. Вы не только сможете просматривать документацию, но и отправлять запросы, и получать ответы.


Также возможно сгенерировать непосредственно клиента или сервер по спецификации API Swagger, для этого нужен генератор кода Swagger-Codegen.


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


Вы найдете все примеры представленные тут в моем репозитории.


Создание REST API


Чтобы документировать API, для начала напишем его :smile: Вы можете перейти к следующей главе, чтобы не тратить время.


Добавим примитивные контроллеры и одно DTO. Суть нашей системы программа лояльности пользователей.


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


В качестве DTO у нас будет класс UserDto это пользователь нашей системы. У него пять полей, из которых 3 обязательны: имя, уникальный ключ, пол пользователя, количество баллов, дата регистрации


public class UserDto {    private String key;    private String name;    private Long points = 0L;    private Gender gender;    private LocalDateTime regDate = LocalDateTime.now();    public UserDto() {    }    public UserDto(String key, String name, Gender gender) {        this.key = key;        this.name = name;        this.gender = gender;    }    public static UserDto of(String key, String value, Gender gender) {        return new UserDto(key, value, gender);    }    // getters and setters}

public enum Gender {    MAN, WOMAN}

Для взаимодействия с нашей бизнес-логикой, добавим три контроллера: UserController, PointContoller, SecretContoller.


UserController отвечает за добавление, обновление и получение пользователей.


@RestController@RequestMapping("/api/user")public class UserController {    private final Map<String, UserDto> repository;    public UserController(Map<String, UserDto> repository) {        this.repository = repository;    }    @PutMapping(produces = APPLICATION_JSON_VALUE)    public HttpStatus registerUser(@RequestBody UserDto userDto) {        repository.put(userDto.getKey(), userDto);        return HttpStatus.OK;    }    @PostMapping(produces = APPLICATION_JSON_VALUE)    public HttpStatus updateUser(@RequestBody UserDto userDto) {        if (!repository.containsKey(userDto.getKey())) return HttpStatus.NOT_FOUND;        repository.put(userDto.getKey(), userDto);        return HttpStatus.OK;    }    @GetMapping(value = "{key}", produces = APPLICATION_JSON_VALUE)    public ResponseEntity<UserDto> getSimpleDto(@PathVariable("key") String key) {        return ResponseEntity.ok(repository.get(key));    }}

PointContoller отвечает за взаимодействие с баллами пользователя. Один метод этого контроллера отвечает за добавление и удаление балов пользователям.


@RestController@RequestMapping("api/user/point")public class PointController {    private final Map<String, UserDto> repository;    public PointController(Map<String, UserDto> repository) {        this.repository = repository;    }    @PostMapping("{key}")    public HttpStatus changePoints(            @PathVariable String key,            @RequestPart("point") Long point,            @RequestPart("type") String type    ) {        final UserDto userDto = repository.get(key);        userDto.setPoints(                "plus".equalsIgnoreCase(type)                     ? userDto.getPoints() + point                     : userDto.getPoints() - point        );        return HttpStatus.OK;    }}

Метод destroy в SecretContoller может удалить всех пользователей.


@RestController@RequestMapping("api/secret")public class SecretController {    private final Map<String, UserDto> repository;    public SecretController(Map<String, UserDto> repository) {        this.repository = repository;    }    @GetMapping(value = "destroy")    public HttpStatus destroy() {        repository.clear();        return HttpStatus.OK;    }}

Настраиваем Swagger


Теперь добавим Swagger в наш проект. Для этого добавьте следующие зависимости в проект.


<dependency>    <groupId>io.swagger.core.v3</groupId>    <artifactId>swagger-annotations</artifactId>    <version>2.1.6</version></dependency><dependency>    <groupId>org.springdoc</groupId>    <artifactId>springdoc-openapi-ui</artifactId>    <version>1.5.2</version></dependency>

Swagger автоматически находит список всех контроллеров, определенных в нашем приложении. При нажатии на любой из них будут перечислены допустимые методы HTTP (DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT).


Для каждого метода доступные следующие данные: статус ответа, тип содержимого и список параметров.


Поэтому после добавления зависимостей, у нас уже есть документация. Чтобы убедиться в этом, переходим по адресу: localhost:8080/swagger-ui.html


Swagger запущенный с дефолтными настройками


Также можно вызвать каждый метод с помощью пользовательского интерфейса. Откроем метод добавления пользователей.



Пока у нас не очень информативная документация. Давайте исправим это.


Для начала создадим класс конфигурации сваггера SwaggerConfig имя произвольное.


@Configurationpublic class SwaggerConfig {    @Bean    public OpenAPI customOpenAPI() {        return new OpenAPI()                .info(                        new Info()                                .title("Example Swagger Api")                                .version("1.0.0")                );    }}

  • title это название вашего приложения
  • version версия вашего API

Эти данные больше для визуальной красоты UI документации.


Добавление авторов


Добавьте разработчиков API, чтобы было понятно, кто в ответе за это безобразие


@Beanpublic OpenAPI customOpenAPI() {    return new OpenAPI()            .info(                    new Info()                            .title("Loyalty System Api")                            .version("1.0.0")                            .contact(                                    new Contact()                                            .email("me@upagge.ru")                                            .url("https://uPagge.ru")                                            .name("Struchkov Mark")                            )            );}

Разметка контроллеров


Переопределим описания контроллеров, чтобы сделать документацию понятнее. Для этого пометим контроллеры аннотацией @Tag.


@Tag(name="Название контроллера", description="Описание контролера")public class ControllerName {    // ... ... ... ... ...}

Добавили описание контроллеров в Swagger


Скрыть контроллер


У нас есть контроллер, который мы хотим скрыть SecretController. Аннотация @Hidden поможет нам в этом.


@Hidden@Tag(name = "Секретный контролер", description = "Позволяет удалить всех пользователей")public class SecretController {    // ... ... ... ... ...}

Аннотация скрывает контроллер только из Swagger. Он все также доступен для вызова. Используйте другие методы для защиты вашего API.


Наша документация стала намного понятнее, но давайте добавим описания для каждого метода контроллера.


Разметка методов


Аннотация @Operation описывает возможности методов контроллера. Достаточно определить следующие значения:


  • summary короткое описание.
  • description более полное описание.

@Operation(    summary = "Регистрация пользователя",     description = "Позволяет зарегистрировать пользователя")public HttpStatus registerUser(@RequestBody UserDto userDto) {    // ... ... ... ... ...}

Метод с аннотацией Operation


Разметка переменных метода


При помощи аннотации Parameter также опишем переменные в методе, который отвечает за управление баллами пользователей.


public HttpStatus changePoints(    @PathVariable @Parameter(description = "Идентификатор пользователя") String key,    @RequestPart("point") @Parameter(description = "Количество баллов") Long point,    @RequestPart("type") @Parameter(description = "Тип операции") TypeOperation type) {    // ... ... ... ... ...}

С помощью параметра required можно задать обязательные поля для запроса. По умолчанию все поля необязательные.


Разметка DTO


Разработчики стараются называть переменные в классе понятными именами, но не всегда это помогает. Вы можете дать человеко-понятное описание самой DTO и ее переменным с помощью аннотации @Schema


@Schema(description = "Сущность пользователя")public class UserDto {    @Schema(description = "Идентификатор")    private String key;    // ... ... ... ... ...}

Сваггер заполнит переменные, формат которых он понимает: enum, даты. Но если некоторые поля DTO имеют специфичный формат, то помогите разработчикам добавив пример.


@Schema(description = "Идентификатор", example = "A-124523")

Выглядеть это будет так:


Разметка аннотацией Schema


Разметка аннотацией Schema


Но подождите, зачем мы передаем дату регистрации. Да и уникальный ключ чаще всего будет задаваться сервером. Скроем эти поля из swagger с помощью параметра Schema.AccessMode.READ_ONLY:


public class UserDto {    @Schema(accessMode = Schema.AccessMode.READ_ONLY)    private String key;    ...}

Валидация


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


Подробнее о валидации данных в этой статье.


public HttpStatus changePoints(    // ... ... ... ... ...    @RequestPart("point") @Min(0) @Parameter(description = "Количество баллов") Long point,    // ... ... ... ... ...) {    // ... ... ... ... ...}

Давайте посмотрим на изменения спецификации. Для поля point появилось замечание minimum: 0.


Валидация в swagger


И все это нам не стоило ни малейшего дополнительного усилия.


Итог


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


Если нужны более тонкие настройки, то вы без труда сможете разобраться открыв документацию к аннотациям сваггера.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru