Readme Driven Development
Как написать удобную библиотеку
Технари всегда начинают разговор с «нет», потому что думают о том, как это реализовывать, а тут надо «парить»…
В этой статье попробуем разобраться о том, как проектировать программные интерфейсы. Интерфейсы могут быть совершенно разными, однако, есть в них одна общая черта: программисты разрабатывают их для других программистов. И это будет нашим большим плюсом, потому что мы также можем выступать в роли потребителей собственных продуктов. Итак, вы решили разработать библиотеку или сервис. С чего начать?
Один из подходов к проектированию программ был предложен Томом Престоном–Вернером1 одним из основателей GitHub, а услышал я о нём впервые в одном из выпусков DevZen2. Этот подход называется RDD или Readme Driven Development и предлагает начинать проект с написания одного документа: README.md.
Мотивация
Я довольно технически настроенный человек. И каждый раз, когда слышу о какой-то проблеме / задаче / вопросе, мозг сразу начинает искать решение. Хотелось бы чтоб это было достоинством, но скорее это недостаток. Представьте, что рядом с вами ребёнок, пытаясь забить гвоздь, ударил себя по пальцу. Последнее, что поможет ситуации, это объяснение ему, что он не так держал молоток. Эту ситуацию не надо решать аналитически. Но мне довольно трудно оценить ситуацию в целом. Привычка закапываться в детали, когда за мелочами перестаёшь видеть целое.
Поэтому важным моментом при написании readme для меня является отказ от попыток анализа внутренностей. Представьте себе идеальный чёрный ящик. То, каким бы вы хотели его видеть. Только интерфейс, ни шагу внутрь. Представьте, что вы ищете библиотеку для решения своей проблемы, что где-то на Земле есть просветлённый программист, который написал для вас идеальную библиотеку и выложил её в открытом доступе. При таком подходе мелочи и детали не отвлекают с самого начала, а появляются постепенно по мере уточнения интерфейса.
При этом сразу вычерчиваются те механизмы, которыми вы бы хотели управлять как потребитель библиотеки, а от каких быть изолированными. Проблемой многих библиотек, которые я писал, оказывалось то, что они имели слишком большую ответственность. Бэкофы и ретраи, параллелизация и валидация. Я всегда думал на два шага вперёд. Но в итоге это оказывалось слишком жёстким, хрупким, несогласованным. Когда смотришь на интерфейс издалека начинаешь думать интерфейсами и находить, что бэкофы и ретраи в разных случаях должны вести себя похоже, так что это можно реализовать в отдельной библиотеке. А параллелизация слишком сильно зависит от контекста и лучше реализовать её в месте использования.
Философия
В противовес подходу проектирования от реализации часто приводят DDD (Document-Driven Development3). Но полное следование такому подходу приводит к разработке довольно большими итерациями, практически водопадному циклу разработки. В отличии от этого RDD не требует чрезмерно-детального прорабатывания всей системы. Наоборот, написание readme должно быть максимально оторвано от реализации (в адекватном ключе, конечно), то есть не надо закапываться в детали при его написании. Это приводит к такому плюсу, что при написании кода его интерфейс, а значит и readme практически не меняются. Это документ, который будучи написан один раз в дальнейшем лишь развивается, но ни в коем случае не переписывается.
Ещё одним неоценимым плюсом такого подхода является быстрое ревью проекта. Прочитав один короткий документ у человека должно сложиться целостное понимание чтО перед ним находится, какую задачу эта программа решает и как эту программу предполагается использовать. Часто это пригождается и самому автору проекта, ведь время идёт и определённые решения забываются.
Использование
Для того, чтобы использовать такой подход неплохо обзавестись шаблонным readme. Посмотрите на описания проектов, которые вам нравятся (есть неплохая подборка проектов с хорошими readme4). Подумайте над тем, что бы вы хотели узнать о проекте при первом взгляде на него. Выберите пункты и попробуйте написать readme для своего или чужого проекта. И следующий проект начните с написания readme на основе сформированного вами шаблона. Например, вот тут можно найти мой шаблон: https://gist.github.com/vporoshok/24d584cb7b52e56f77d9b91d890c3b4c.
Не забудьте включить в документ примеры использования вашей программы. Именно эти примеры и станут основой для тестов, а дальше и для кода проекта.
Как это работает
Перед началом движения хорошо бы знать точку назначения. Ну или хотя бы направление. Перед написанием программы, конечно, в первую очередь надо сформулировать задачу, которую она будет решать. Довольно часто я сам подходил к этой части довольно халатно, мол сервис авторизации, будет делать всё, что связанно с авторизацией. А управление пользователями: создание, приглашение, блокировка — тоже в этом сервисе будет происходить? На многие вопросы ответы находятся в момент написания или проектирования кода. Таким образом я подстраивал интерфейс программы для упрощения её внутреннего устройства. Но потребитель нашей программы не будет смотреть на её внутренности, он будет использовать её как чёрный ящик. И менять форму ящика под содержимое оказывается порочной практикой.
Можно сказать, что RDD позволяет проектировать сложные системы сверху вниз, а не снизу вверх, как это часто происходит.
Ключевые особенности
- формулирование задачи с чёткими границами ответственности;
- проектирование удобного и гибкого интерфейса;
- примеры использования, которые можно легко превратить в e2e-тесты для проекта;
- минимальная документация (для многих проектов этой документации оказывается достаточно);
- помощь в принятии решения другим людям, выбирающих проект для своих нужд;
Смотрите также
- https://krasimirtsonev.com/blog/article/readme-driven-development
- https://medium.com/@elliotchance/readme-driven-development-3a434b7e253c
- https://deterministic.space/readme-driven-development.html
- https://github.com/noffle/art-of-readme#readme
- http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions
Заключение
Если присмотреться, то можно заметить, что эта статья написана по моему шаблону readme. Полезная штука не только для описания программ, да?