Programming
25 June

Архитектура приложения или как испортить карму на Хабре

Можно много говорить об архитектуре приложения, SOLID, принципах ООП, о таких архитектурных патернов как слоистая или луковая и д.р. шаблоны проектирования. В течение своего опыта я понял одно сколько людей столько и мнений. Когда ты начинающий программист у тебя много амбиций, чуть растешь в квалификации у тебя ощущение что ты все знаешь, и все что сделано до тебя «плохо», и ты обязательно сделаешь лучше… Но годы идут и набранный опыт говорит об обратном. Под катом я попытаюсь кратко, и главное простыми словами, рассказать вам о том как хорошую архитектуру. Как минимум расширяемую и поддерживаемую, за подробностями прошу под кат…

Перво на перво для создания хорошей архитектуры проекта, необходимо определиться с ее признаками:

  1. Архитектура должна быть поддерживаемая.
  2. Расширяемость системы без костылей.
  3. Гибкость настройки, многие задачи должны решаться без изменения программного кода.
  4. Надежность архитектуры.

Первые пункт легкость поддержки решается следуя принципам SOLID, в основном конечно же принципу «Единственности ответственности», по этому архитектура необходимо выбирать основанную на микросервисах или же модульную архитектуру монолитного ядра система. Какой то принципиальной разницы между этими подходами нет. Я для проекта над котором работаю выбрал 2-й подход, модули.

Второй пункт можно решить используя паттерн программирования event-observer либо dispatcher Они похожи друг на друга, по этому не будем заострять внимания. Суть их работы выкинуть какое либо сообщение из модуля который сейчас выполняется, и прослушать при необходимости модулем которому необходимо поработать с данным объектом.

Третий пункт, решается тоже довольно просто, описательную часть сущности, то есть атрибуты сущностей хранить отдельно от самой сущности. Это отсылка к EAV (Entity Attribute Value) Вам не обязательно обрабатывать все поля какой либо сущности для бизнес логики, некие атрибуты несут информативную нагрузку, другие используются для сортировок и фильтрации, и только часть для построения бизнес логики. По этому если сущность храниться как EAV, мы в любой момент можем добавить или убрать ненужный нам атрибут.

Четвертый пункт наших требований это надежность, а значит минимум «костылей» и больше автоматизации. Большинство веб приложений состоит из интерфейсов отображения данных, таблицы, фильтры, сортировка, карточки сущностей. И интерфейсов ввода данных, форм. По этому стоит применять фабрики для форм, фабрики для таблиц, фабрики для карточек. Больше автоматики, в конце концов мы можем абстрагироваться от области представления, и заострить внимание на бизнес-логике и предметных задачах…

И так напрашивается вывод, что бы выстроить хорошую архитектуру, необходимо абстрагироваться, определиться с технологиями и паттернами программирования и выстроить фундамент для начала разработки…

Теперь мы разработали план, определились с требованиями, дальше надо определиться как строить архитектуру. На самом деле Я не понимаю все эти слоистые архитектуры или луковые. Я взял что то от них что то придумал сам, и не вижу в этом ничего такого, если людям просто понять что то значит это правильно. По сути вся архитектура сводиться к незамысловатым шагам:

  • В фундаменте абстракция (абстрактные классы и интерфейсы определяющие контракт тех или иных компонентов системы объедененных в модули)
  • Далее у меня идет слой ядра который запускает модули и ими управляет.
  • Загрузка системы layout'ов
  • После запуска модуля, каждый модуль как отдельный микросервис

Но что же делает архитектуру хорошей? Вопрос не простой, но если все упростить до уровня философских рассуждений то и на этот вопрос найдется ответ. После того как запускается приложение. Мы имеем изолированные друг от друга части, модули. Каждый модуль отвечает только за один функционал системы. Спускаемся дальше каждый модуль, спроектирован как mvc приложение и имеет представление, контроллер, модель. И каждая эта часть модуля тоже отвечает каждый за свое действие. Спускаемся еще глубже и мы увидим что представление тоже имеет некие части, это классы фабрик, и расширения layout's. На самом деле layout'ы это тоже модуль, он подгружается прежде всего, все остальные модули дополняют его, и строят интерфейс (или систему вывода). А как же сделать все это мене зависимым спросите вы? И ответ будет очевиден обсерверы, на каждый рендер блока layout's выбрасывают свои event's достаточно лишь прослушать этот event, observer'ом в вашем приложение, и добавить нужное обновление блока в слоях, и получить соответствующий вывод. Так же и многие модули имеют свои евенты, на которые подписаны другие модули и способны добавлять/либо обновлять данные в переданном наборе. Все это приводит к тому что в приложение, модули мало связанны друг с другом и могут жить друг без друга.

В свете вышесказанного возникает резонный вопрос, если у нас один модуль слушает другой то необходимо иметь какую то систему по управлению зависимостями для этих модулей. То есть модуль от которого зависит другой модуль мы должны запустить в первую очередь а тот который зависимый мы должны запустить после. Так и родилась простая реализация зависимости, мы создаем очередь для запуска модулей и просто сортируем ее таким образом что бы те модули от которых зависит какие либо другие, загружались в первую очередь, после загрузки ядра конечно же.

В заключение, могу сказать следующее. Хорошая архитектура это не такая сложная и долговременная задача, что бы на ней экономить. И в конечном итоге на помогает более эффективнее расходовать ресурсы и время. Ведь поменять настройку в панеле управления это пятиминутное дело. Написать две строки для добавление тоже не так много времени. А вот сверстать вывод, каждый чих переверстывать, дебажить большие объемы данных это уже время которое во много раз превышает время разработки стратегии построения архитектуры.

-59
4.9k 15
Comments 49