Помните эпический момент из фильма «Матрица», где Нео пришел к Пифии за разъяснениями по своей миссии. Но в начале он узнал от маленького медитирующего мальчика, чуть ли не основную идею фильма. Тот сидел в позе лотоса и просто гнул ложки, а потом сообщил: «Не пытайся согнуть ложку, это невозможно, ложки не существует». Фильм очень удачно построен на целом обилии философских высказываний, которые слеплены великолепным видеорядом. Но какую пользу программист может извлечь из этого утверждения, что ложки не существует? Давайте посмотрим на то, как обычно решаются задачи. Предположим, жена дает вам семейный портрет в раме и просит повесить его на стену. Если попробовать решить задачу в лоб, то мы бы подошли к стене, прижали раму к обоям и силой воли постарались закрепить ее там. Но как только мы отпустим раму, то она сразу упадет на пол. Естественно, вы так не поступите, а пойдете в кладовую, достанете инструменты, прибьёте/прикрутите гвоздь/шуруп в стену и затем повесите на ней раму с помощью петли. Пример выше показывает, что любой здравомыслящий человек осознает необходимость сделать несколько шагов, для выполнения поставленной задачи. В понимании жены повесить картину на стену, это вполне понятная функция, которая выполняется мужем, эта функция для нее существует. Но в понимании мужа, повесить картину – это только пожелание, которое нужно выполнить с помощью определенных действий, для исполнителя в данном случае не существует такой функции. Если развивать рассуждения дальше, то для человека умелого прибить гвоздь в стену – это вполне осязаемая функция, мы же берем молоток в руки и выполняем определенные удары по шляпке гвоздя. Только, если рассмотреть это действие с детализацией до человеческой руки, то мы увидим, что здесь мышцы сжимают и разжимают кости, скрепленные суставами, когда к ним поступают определенные сигналы от нервной системы. Процесс детализации можно продолжать, мышцы в свою очередь состоят из клеточных волокон, которые реагируют на электрические сигналы и меняют свою форму. И так вплоть до молекул, атомов, электронов и затем кварков, вероятно это бесконечный процесс вглубь. В итоге мы видим, что ни на одном из этих уровней не существует четкого определения функции, есть только конкретные результаты текущих действий, которые абстрагированы от самой основной цели этой деятельности, т.е. от изначальной «кажущейся функции». Это и пытается объяснить мальчик своей фразой: «не пытайся согнуть ложку, это невозможно», точно так же как «силой мысли заставить картину висеть на стене». Для исполнения функции всегда необходимо проделать декомпозицию и определить требуемые комбинации между какими-то низкоуровневыми компонентами. Функция лишь некая видимость результирующего взаимодействия. Хорошо, говорить про тривиальность задачи с картиной, когда все необходимые знания и умения есть почти у каждого человека. Но сложности возникают, когда решение совсем не очевидно. И такое часто случается при проектировании программных систем. Многие неопытные программисты всегда пытаются решить задачу в лоб. Если нужно сделать кнопку подписаться на новости сайта, то часто это выполняется всего парочкой запросов из формы на сайте и затем напрямую в базу данных, причем с конкретными SQL-запросами. На первый взгляд это быстрое решение срабатывает, но это всего лишь дословное описание функции, что требовалось, то и сделали. Проблемы начинаются, когда заказчику хочется добавить выбор: на какие новости будет подписываться клиент, добавить уведомление администратору или группе менеджеров, что появился новый подписчик. А затем, вообще, интеграцию с внешним сервисом рассылки. Конечно, переписать десять строчек кода в этом случае будет легко, но чем больше новых требований будет появляться, тем сложность начнет расти в геометрической прогрессии. А если рассмотреть тривиальную процедуру подписки более детально, и выделить из этого несколько атомарных операций, которые выполняются независимо друг от друга, тогда изменения в будущем будет проще выполнять. Минимально нужно определить, какая часть этого процесса с большой вероятностью измениться в будущем и максимально инкапсулировать воздействие этих будущих изменений в одном компоненте, чтобы другие модули совершенно ничего не знали, о том, что запись нового пользователя для рассылки теперь идет не в MySQL базу, а в облачный сервис. С другой стороны и клиентская часть может меняться и об этом не должно знать ядро подписок. Вполне, вероятно, что вместо email адреса, будет выступать номер телефона или логин в телеграме или любой другой социальной сети. Постепенно задавая себе уточняющие вопросы можно выделить самостоятельные компоненты и сущности, которые сформируют правильную архитектуру системы. И слаженное выполнение последовательности действий даст нам нужный результат внутри этой системы. Причем при таком подходе мы получаем еще одну большую выгоду, в будущем, когда потребуется совершенно новое поведение, мы просто можем поменять последовательность шагов или добавить какие-то новые сущности, без необходимости переделывать готовые и отлаженные компоненты. Чтобы стать успешным программистом-архитектором, необходимо перестать «гнуть ложки», нужно научить свой разум сразу смотреть в глубину процесса и выявлять атомарные операции, из которых состоит процесс, и уже с помощью комбинации этих действий проектировать алгоритм системы.