Вторая часть про откладывание важных решений на попозже
В первой части мы закончили на том, что в условиях неопределенности мы либо принимаем решение в ненужный момент - и почти наверняка приходим затем к необходимости всё переделать (или бесконечно продолжать доказывать, что решение было верным, даже если в этом не верим, см. факты и заблуждения о профессиональном программировании про планы), либо пытаемся отложить принятие решения до last responsible moment.
Теперь о том, при чем тут архитектура и архитектор.
Соответственно, одна из ценностей intentional архитектуры в целом и архитектора в частности в таких условиях и есть в том, чтобы помочь команде (ну и себе, конечно):
🔹 сделать так, чтобы можно было отложить принятие решения до last responsible moment (то есть буквально, помочь перенестись в будущее)
🔹 либо, если это невозможно, помочь снизить стоимость изменения этого решения в будущем.
Причем, если часть «архитектурных практик», например фиксацию архрешений, я считаю масштабируемой общественной деятельностю команд, то вот эти действия - следствие архитектурного mindset-а, поэтому как бы и есть один из ожидаемых выхлопов от архитектора, как от отдельного человека/ позиции/ роли. Ключевой выхлоп от этих действий — они должны расширять опции в будущем, а не ограничивать их.
Отличными инструментами для этого являются:
🔹 использование слоёв абстракций (многие из которых реально существуют в языках программирования «из коробки», но это не все понимают)
🔹 выбор в пользу обратимых (reversable by design) решений
🔹 декомпозиция одного решения на несколько (а на самом деле — декомпозиция одного «сложного» решения на несколько простых)
Если на конкретных, простых примерах, то:
◾️ использовать Spring Data или любой другой «коробочный» механизм абстракции хранения в коде сервиса, чтобы иметь возможность менять БД, не меняя бизнес-кода — это слой абстракции. Можно пойти дальше, и чтобы не зависеть от готовых реализаций Spring Data или вообще фреймворка целиком, сделать свой собственный Required Interface с самыми универсальными и безусловными операциями над данными в БД (сохранить с id, прочитать по id). Соответственно, этим мы можем и отложить выбор БД (если задача стартовать разработку бизнес-кода пораньше), и сделать его обратимым (замена БД не будет затрагивать код). Использование абстрактных API для взаимодействия между сервисами — туда же.
◾️ добавить в структуру системного объекта +4 новых атрибута, которые сейчас не нужны этому объекту, но есть ненулевая вероятность, что понадобятся в будущем — это обратимое решение или решение с опциями в будущем. Добавить 4 атрибута стоит 30 минут суммарного времени работы аналитика, разработчика и тестировщика, а стоимость изменения решения «не использовать эти данные» на противоположное (то есть «использовать эти данные») будет 0.
◾️ вместо решения «как нам разбить этот монолит на микросервисы» (да, такие задачи есть в 2к20+ году) принять пачку отдельных решений «как редизайнить такую-то функцию для решения такой-то задачи (функциональной или нефункциональной») — это декомпозиция одного решения на несколько. Их на самом деле и есть несколько, просто мозг слишком абстрагируется и превращает конкретную задачу в общую слишком сильно. Здесь редизайн каждой отдельной функции или взаимодействия будет выполняться именно в тот момент, когда это будет необходимо, и у нас уже будет достаточно информации для этого.
Да, таким образом принятие части архитектурных решений превращается в дизайн того, как бы нам эти решения не принимать (что может раздражать фанатов «поиграться в техничку» и свидетелей секты System Design Interview). Но если мы вспомним, что архитектура должна помогать нам обеспечить в том числе экономически эффективный процесс производства и развития систем и продуктов, это будет выглядеть логично.
Post #50
257
- 🔥 3