Теперь пройдемся еще раз по диаграммам. А точнее, по диаграммам данных (data flow). Допустим, с майндмапами вам уже все понятно (или с проектом все понятно и без них) и хочется двинуть дальше.
Далее, все что рассказываю, касается разработки софта, как оно в железе - не знаю. Таких сложных железок, чтобы требовали отдельных диаграмм у меня не было. Вообще, существует много диаграмм (данных, состояний, классов, use cases и т.п.). Мало кто делает полный набор, а генерация по диаграммам кода обычно работает только в идеальном шарообразном мире, или в воображении менеджеров по продажам, которые хотят вам втюхать очередную волшебную тулзу за дохрелион денег.
Возможно на очень больших проектах, где толпа людей, причем сомнительной квалификации, есть смысл прорисовывать все до деталей (потому что выхода нет). Но в ситуациях попроще обычно удобнее отрисовать и верифицировать "самое мясо", и переключиться непосредственно к программированию:
- По мере роста деталей затраты времени на диаграммы возрастают, и эта зависимость не линейна.
- Когда в код вносятся изменения - синхронизировать диаграммы это куча лишней работы. Примерно как возня с исправлением тестов, если их нафигачить "из принципа", до того как внутренние API достигли определенной стабильности.
Нет смысла упираться в абстрактные принципы. Важен баланс. Нам ведь не надо рисовать диаграммы ради вселенской справедливости или красивого вида. Мы обычно хотим с минимальными усилиями "правильно" разбить систему на части, чтобы не подставляться под дорогие переделки. Что будет балансом в конкретно вашем случае - можете решить только вы. Здесь универсальных советов, к сожалению, нет.
Конечно, всегда найдутся исключения, но я рассказываю про основной подход, с чего хотя бы начать, когда от страха дрожат ручки и дергается глазик. Если задуматься, то суть большинства систем - обработка данных. Есть черный ящик, у которого на входе ручки, за которые дергает безумный юзер, а на выходе (допустим) индикатор. Если проектируем библиотеку, то входы и выходы обзывают словом API. Как-то так, если совсем кратко и с упрощениями. Обращаю особое внимание, не надо путать данные с событиями. Данные можно какбэ "потрогать руками". В событиях проще запутаться. Пример исключения, когда выбирать не приходится - конечный автомат. Там без событий никак. Но не стоит усложнять себе жизнь раньше времени. Диаграммы данных вам понадобится рисовать практически всегда. Остальное - по обстоятельствам.
Профит: если вам удалось сделать корректную диаграмму данных, то налажать потом в коде практически невозможно

.
Имейте в виду, что процесс дизайна итеративный. Не бойтесь ошибиться. Нарисовать правильную диаграмму с первого раза практически невозможно. Делается набросок, потом верифицируется, что данные нигде не профукали и не намагичили, вносятся коррекции и уходим на второй круг.
Итак, начинаем с того, что фиксируем входы и выходы. Т.к. если мы не знаем, "что обрабатывать", то и внутренние блоки станут перемалывать какую-то туфту, и ничего хорошего не выйдет. На самом верхнем уровне входы и выходы называются "use cases" - как юзер захочет подергать ручки, как ему будет удобно дергать API и что он захочет получить взамен. Обычно use cases сначала выглядят несколько сумбурно, поэтому проще их выписать в столбик, чтобы найти что-то общее. Или откатиться на шаг назад и прогнать через mind map для особо тяжелых случаев.
Итого, у нас должно получиться:
- Исходные точки
- Стрелочки (данных), которые выходят из этих точек или приземляются в них.
Ну и остается дорисовать блоки, которые эти данные как-то переколбасят.
На что стоит обратить внимание:
- На "стрелочках" обязательно должны быть именно данные. В идеале - подписать. В крайнем случае вы как минимум должны быть готовы ответить до мельчайших деталей, что гонится по стрелочке. Если по стрелочке гонится фик знает что - хрен вам, а не полезная диаграмма в результате.
- Надо постоянно верифицировать, что данных на входе (стрелочек) будет достаточно для работы блока, чтобы выплюнуть то что хочется. Если что-то пропустили - дорисовываем (или помечаем отдельно). Если не подумав нарисовали лишнее - убираем.
- Бывает, что данных очень много. Например конфиг с 20 параметрами. Такую часть иногда удобнее записать сразу в виде кода, чтобы не превращать чертеж в месиво. Но верификацию целостности все равно надо проделывать.
- Содержимое стрелок - основа для API (внешний или внутренних). Еще один повод отнестись к ним серьезно, а не использовать их в качестве декоративных соединителей.
Примеры "стрелок":
- Фиговый вариант - "устройство ввода". Непонятно, какие данные и как оно выплевывает.
- Дельный вариант - "коды клавиш, байты, с клавиатуры".
Примеры очень упрощенные, только чтобы продемонстрировать суть объяснений.
По блокам внутри диаграммы. Тут универсального рецепта нет. Могу только посоветовать придерживаться некоторых ограничений:
- Избегайте большого количество блоков. Если диаграмма распухает - уводите "лишнее" в иерархии. Обычно советуют не превышать 7-9 блоков, но это субъективно. Если у вас сверхмозг - рисуйте хоть 20, раз можете объять разумом
. Главное - не забывайте верифицировать входы-выходы у каждого блока. И не забывайте, что если планируете показывать диаграммы другим - у них может быть не такой сверхмозг как у вас. - Избегайте "пустых" преобразований форматов данных и бездумных шаблонов. Типичная ошибка программиста - нарисовать класс с красивым названием "потому что так правильно", и потом пытаться подогнать стрелочки под этот класс. С надеждой, что в итоге все сойдется как надо. Если вас в качестве гарантий устраивает молитва и вера в лучшее - на здоровье. Если нужны гарантии посерьезнее - стоит опираться на содержимое "стрелочек", и дорисовывать блоки под них а не наоборот. Результат может получится абсолютно не такой, как вы предполагали в начале. Причем проще и лучше
. Убеждался несколько раз.
Возможно, в конце у вас получится совсем простая диаграмма из пары-тройки блоков, и вы подумаете "неужели из-за такой тривиальщины я страдал фигнёй". Но ведь смысл именно в том, чтобы понять, как сделать просто, а не наворотить чумную вундервафлю. На практике у меня получались рисунки с 3-5 блоками, и очень редко - с подуровнем для одного-двух блоков. Просто я не вижу смысла упираться в диаграмму как в самоцель. Рисую только до той степени, которая позволить двинуться дальше - продолжить в коде.
Можно делать иначе, сложнее и т.п. Все зависит от мастерства, потребностей и т.п. Я описал один из вариантов, с чего можно начать. Очень часто этого оказывается достаточно.