Помните эпический момент из фильма «Матрица», где Нео пришел к Пифии за разъяснениями по своей миссии. Но в начале он узнал от маленького медитирующего мальчика, чуть ли не основную идею фильма. Тот сидел в позе лотоса и просто гнул ложки, а потом сообщил: «Не пытайся согнуть ложку, это невозможно, ложки не существует».
Фильм очень удачно построен на целом обилии философских высказываний, которые слеплены великолепным видеорядом.
Но какую пользу программист может извлечь из этого утверждения, что ложки не существует?
Тривиальный пример
Давайте посмотрим на то, как обычно решаются задачи. Предположим, жена дает вам семейный портрет в раме и просит повесить его на стену. Если попробовать решить задачу в лоб, то мы бы подошли к стене, прижали раму к обоям и силой воли постарались закрепить ее там. Но как только мы отпустим раму, то она сразу упадет на пол. Естественно, вы так не поступите, а пойдете в кладовую, достанете инструменты, прибьёте/прикрутите гвоздь/шуруп в стену и затем повесите на ней раму с помощью петли.
Пример выше показывает, что любой здравомыслящий человек осознает необходимость сделать несколько шагов, для выполнения поставленной задачи. В понимании жены повесить картину на стену, это вполне понятная функция, которая выполняется мужем, эта функция для нее существует. Но в понимании мужа, повесить картину – это только пожелание, которое нужно выполнить с помощью определенных действий, для исполнителя в данном случае не существует такой функции. Если развивать рассуждения дальше, то для человека умелого прибить гвоздь в стену – это вполне осязаемая функция, мы же берем молоток в руки и выполняем определенные удары по шляпке гвоздя. Только, если рассмотреть это действие с детализацией до человеческой руки, то мы увидим, что здесь мышцы сжимают и разжимают кости, скрепленные суставами, когда к ним поступают определенные сигналы от нервной системы.
Процесс детализации можно продолжать, мышцы в свою очередь состоят из клеточных волокон, которые реагируют на электрические сигналы и меняют свою форму. И так вплоть до молекул, атомов, электронов и затем кварков, вероятно это бесконечный процесс вглубь.
В итоге мы видим, что ни на одном из этих уровней не существует четкого определения функции, есть только конкретные результаты текущих действий, которые абстрагированы от самой основной цели этой деятельности, т.е. от изначальной «кажущейся функции».
Это и пытается объяснить мальчик своей фразой: «не пытайся согнуть ложку, это невозможно», точно так же как «силой мысли заставить картину висеть на стене». Для исполнения функции всегда необходимо проделать декомпозицию и определить требуемые комбинации между какими-то низкоуровневыми компонентами. Функция лишь некая видимость результирующего взаимодействия.
Хорошо, говорить про тривиальность задачи с картиной, когда все необходимые знания и умения есть почти у каждого человека. Но сложности возникают, когда решение совсем не очевидно. И такое часто случается при проектировании программных систем.
Реальная задача
Многие неопытные программисты всегда пытаются решить задачу в лоб. Если нужно сделать кнопку подписаться на новости сайта, то часто это выполняется всего парочкой запросов из формы на сайте и затем напрямую в базу данных, причем с конкретными SQL-запросами. На первый взгляд это быстрое решение срабатывает, но это всего лишь дословное описание функции, что требовалось, то и сделали.
Проблемы начинаются, когда заказчику хочется добавить выбор: на какие новости будет подписываться клиент, добавить уведомление администратору или группе менеджеров, что появился новый подписчик. А затем, вообще, интеграцию с внешним сервисом рассылки. Конечно, переписать десять строчек кода в этом случае будет легко, но чем больше новых требований будет появляться, тем сложность начнет расти в геометрической прогрессии.
Декомпозиция системы
А если рассмотреть тривиальную процедуру подписки более детально, и выделить из этого несколько атомарных операций, которые выполняются независимо друг от друга, тогда изменения в будущем будет проще выполнять. Минимально нужно определить, какая часть этого процесса с большой вероятностью измениться в будущем и максимально инкапсулировать воздействие этих будущих изменений в одном компоненте, чтобы другие модули совершенно ничего не знали, о том, что запись нового пользователя для рассылки теперь идет не в MySQL базу, а в облачный сервис. С другой стороны и клиентская часть может меняться и об этом не должно знать ядро подписок. Вполне, вероятно, что вместо email адреса, будет выступать номер телефона или логин в телеграме или любой другой социальной сети.
Постепенно задавая себе уточняющие вопросы можно выделить самостоятельные компоненты и сущности, которые сформируют правильную архитектуру системы. И слаженное выполнение последовательности действий даст нам нужный результат внутри этой системы.
Причем при таком подходе мы получаем еще одну большую выгоду, в будущем, когда потребуется совершенно новое поведение, мы просто можем поменять последовательность шагов или добавить какие-то новые сущности, без необходимости переделывать готовые и отлаженные компоненты.
Вывод
Чтобы стать успешным программистом-архитектором, необходимо перестать «гнуть ложки», нужно научить свой разум сразу смотреть в глубину процесса и выявлять атомарные операции, из которых состоит процесс, и уже с помощью комбинации этих действий проектировать алгоритм системы.
Комментарии (7)
lynxp9
14.10.2022 06:42+2В таком случае можно столкнуться с оверинженерингом, когда в проекте пара функций реализованных в лоб превращаются в теже пару функций, но реализованных через гораздо большее количество кода. С одной лишь ремаркой, проект не будет рости.
Rumantic Автор
14.10.2022 06:46-3Я программирую уже 17 лет и всегда, когда думаю: "проект не будет расти", происходит ровно наоборот. И моя быстрая нашлепка потом в итоге создает проблему.
lynxp9
14.10.2022 08:52+1Я хотел сказать, что можно писать небольшие проекты без оглядки на архитектуру, опираясь на библиотеки или фреймворк.
Со временем выработывается представление о том, как скрещивать свой код с используемыми инструментами в виде какого-то патерна. И далее, либо использовать этот "выкристализованный" патерн в каждом проекте. Либо брать и кодить с минимальным внесением "проектных знаний" об архитектуре. То есть у каждого по своему, но по моему опыту все можно сделать без умного академизма и оно будет работать.
AtomMushroom
14.10.2022 12:05+2Статья по сути ни о чем. Какой уже это по счету случай, когда человек на хабре пытается связать матрицу с IT?
v3shin
14.10.2022 12:05+2Проблема в том, что никогда не знаешь, куда дальше по требованию заказчика будет двигаться проект. Можно попытаться охватить все возможные варианты и долго ковыряться с кодом, пытаясь решить с десяток задач "на перспективу"... но задача-то вот она уже, и ее надо выполнить. Так что, YAGNI - и вперед. Все равно через некоторое время придется рефакторить, если заказчик будет хотеть развивать функционал.
napa3um
Интроспекция - известная трясина для ума, ведь кажется, что мы обозреваем свои объективные механизмы мышления, но на самом деле активно конструируем (сочиняем) метафизические идеализации в процессе так называемого «наблюдения». :)
MentalBlood
Ну так "мы обозреваем свои объективные" как бы намекает на подвох )