🔥

Тред (@bespoyasov)


@jsunderhood Реквестирую тред про интервью по системному дизайну и архитектуре. У меня завтра собеседование, а инфы по фронтенду кот наплакал 🌚
Теперь немного о собственно проектировании. Допустим, мы знаем, что нашему проекту нужна суровая масштабируемость. Что делать? Первым делом стоит взять ручку, бумажку и пойти «программировать ногами» 😃 twitter.com/lizuschiykotik…

Мы (люди) плохо умеем прогнозировать будущее. Проектирование систем — это прогнозирование будущего. Чем больше исходных данных мы насобираем, тем больше вероятность, что мы правильно составим «карту территории».

(О соотношении карты и территории: ru.wikipedia.org/wiki/Соотношен…)

Что нам необходимо знать? - Какие задачи перед нами стоят. - Какое решение считается удовлетворительным. - Какие есть ограничения.

Чего мы хотим добиться: - Доменный слой должен быть самостоятельным и независимым. - Адаптеры должны подстраивать внешние сервисы под нужды нашего приложения, а не наоборот. - ...

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

Я недавно писал пост о дизайне системы с помощью слоёв и DDD: bespoyasov.ru/blog/generatin… Давайте используем его как пример и ответим на вопросы.

Так-с, обед закончился 😅 Ответим на вопросы после работы!

Продолжим 🙂 На какие вопросы мы ищем ответы? В первую очередь — какие перед нами стоят задачи. Потому что ответ на этот вопрос определит, что будет содержать доменный слой.

Кроме этого — какое решение мы посчитаем достаточным, какая требуется глубина проработки. Если мы делаем приложением только под браузер — это одно, а если мы пишем его для браузера, React Native, и Ноды — уже другое.

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

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

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

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

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

- ...Всё ли нормально с направлением зависимостей; - Следую ли я принципам SOLID; - Что будет, если захочу заменить реализацию какого-то модуля на другую; - Сколько понадобится ресурсов, чтобы поменять платформу, инфраструктуру, whatever.

Обычно получается нечто вроде такой диаграммы (из поста с деревьями):
notion image

Я не стал упарываться, покрывая веб-платформу адаптерами с ног до головы, так как был уверен, что мне это не понадобится. Но зато при проектировании я заметил, что модуль геометрии придётся разбить на 2 отдельных интерфейса. ota-solid.now.sh/isp

Также помогает выделить Driver (управляющие), и Driven (управляемые) адаптеры:
notion image

(На эту тему ещё раз посоветую эту статью herbertograca.com/2017/11/16/exp…)

Диаграмма помогает не писать сразу код, а сперва приметиться на бумаге — «а оно вообще поедет?». Иногда диаграммы помогают обнаружить ошибки проектирования: - функциональность засунули не туда; - модули слишком сильно зацеплены; - ...

- ...Нужна шина событий, чтобы связать какие-то сущности; - Нарушаем SRP, DIP, ISP и прочее. Если паровоз на бумаге поедет, то можно думать в сторону кода.