Архитектура приложения - особенности, описание и требования

Архитектура приложения – это то, без чего сложно обойтись даже при создании небольшого проекта. А уж создание без нее достойного более-менее крупного представителя программного обеспечения, работающего без значительных проблем и с удовлетворительной результативностью – дело вообще не мыслимое. Что же собой представляет архитектура приложения? Каким рекомендациям нужно следовать, чтобы создать качественный продукт?

Вводная информация

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

О критериях

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

На что делать ставку?

Работая с архитектурой, внимание следует уделить:

  1. Эффективности системы. То есть проектирование архитектуры приложения должно создавать такое программное обеспечение, которое сможет решать поставленные задачи и хорошо выполнять возложенные на него функции в разных условиях. В первую очередь здесь следует упомянуть надежность, производительность, безопасность, масштабируемость (способность справляться с увеличением нагрузки).
  2. Гибкости системы. Любое, даже самое совершенное приложение приходится со временем менять. Ведь могут измениться существующие требования или добавиться новые. Чем удобнее и быстрее этот процесс можно завершить с меньшим количеством ошибок и проблем, тем конкурентоспособнее и гибче система. Поэтому необходимо следить за тем, чтобы принятый подход не «вырубал в камне» все действия.
  3. Расширяемости системы. Возможность добавить новые функции и сущности, не нарушая основную структуру, говорит о продуманности приложения. На начальном этапе имеет смысл закладывать исключительно основной и необходимый функционал. Но при этом должна быть предусмотрена возможность наращивания предоставляемых возможностей по мере возникновения необходимости. Причем таким образом, чтобы на это тратилось минимальное количество сил. Это настолько важно, что даже сформулировано в виде второго принципа SOLID: программные сущности открыты для расширения, закрыты для модификации. То есть архитектура должна быть такой, чтобы можно было написать новый код, но не пришлось менять уже существующий.

А что еще?

Этими тремя критериями архитектура программного приложения не ограничена:

  1. Масштабируемость разработки. Архитектура должна предусматривать возможность обеспечить параллельность процесса разработки, чтобы увеличить количество людей, которые работают над проектом.
  2. Тестируемость приложения. Код, который легко проверять, содержит в себе меньшее количество ошибок и надежнее работает. К тому же это еще и подталкивает к формированию хорошего дизайна кода, что также облегчает последующую работу с ним.
  3. Возможность повторного использования. Систему следует проектировать таким образом, чтобы ее отдельные фрагменты можно было применять в других проектах.
  4. Хорошая структурированность, читаемость и понятность кода. Над программами, как правило, работает большое количество людей. Часто встречается ситуация, когда приходят новые или уходят старожилы. Архитектура приложения должна учитывать это. И все наработки должны давать возможность относительно быстро и легко разобраться в создаваемой системе новым людям. В этом помогает хорошая структурированность проекта, отсутствие дублирования, адекватное оформление и документация сопровождения (необязательно, но желательно).

И что же из этого следует?

Несмотря на наличие большого количества критериев, как правило, приоритетной считается задача снижения сложности. А для этого ничего, кроме как делить на части, не придумали. Большинству людей это известно как принцип «разделяй и властвуй». Но если говорить профессиональным языком, то это обычная иерархическая декомпозиция. Что это значит на практике? Есть одна большая целевая система. Например: архитектура корпоративных программных приложений. Она состоит из множества простых подсистем. Каждая из них имеет свои элементы. И так до тех пор, пока не будут выделены небольшие части, понятные и легкие в работе. Что хорошо, так это то, что такое решение является не только единственным известным, но еще и универсальным. Кроме снижения сложности оно позволяет еще обеспечить гибкость системы, предоставляет возможности для масштабирования и повышает устойчивость конечного продукта.

Рассмотрение примера

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

Превращение спагетти-кода в конструктор

Правильный подход позволяет превращать готовый продукт в набор модулей (подпрограмм), которые взаимодействуют между собой по простым и хорошо определенным правилам. Это позволяет контролировать сложность создаваемого приложения и получать все преимущества, которые предоставляет отменная архитектура:

1. Масштабируемость – позволяет расширять систему и улучшать ее производительность благодаря добавлению новых модулей.

2. Ремонтопригодность – изменение одной части программы не требует вмешательства в другие.

3. Заменяемость – несколько модулей легко могут выполнять нужные функции.

4. Тестируемость – часто программы можно отделить и отдельно проверить (починить).

5. Переиспользование – отдельный модуль можно использовать в других программах и окружениях.

6. Сопровождаемость – программа легко разбивается на составляющие части, которые несложно понять.

Как выглядит сам процесс?

В первую очередь необходимо произвести моделирование архитектуры приложения. Для этого используются как специальные программы, так и обычная бумага. Первоначально необходимо обозначить все элементы, а также установить между ними взаимосвязь, которая в последующем и будет реализована. Затем встает вопрос о том, как проводить декомпозицию. Условно говоря, есть иерархический, функциональный и комбинированный этапы. При этом нельзя сказать, что архитектура web-приложений клиент-серверной модели должна строиться по определенному подходу – все зависит от поставленных целей и решаемых задач. Для того чтобы получить хороший результат, необходимо правильно сделать декомпозицию. А здесь уже следует понимать, что считается правильным и как это лучше реализовать. Чтобы получить хорошую архитектуру, надо знать, как адекватно делать декомпозицию системы. А значит, необходимо понимать, какая декомпозиция считается правильной и каким образом ее лучше проводить. Рассмотрим, как будет выглядеть архитектура серверного приложения такого типа.

Иерархическая декомпозиция

Многие допускают здесь ошибку, рубя приложение сразу на сотни классов. Более правильный подход – разбить систему на крупные модули (пакеты), описывающие ее работу в общем виде. Затем они анализируются и при необходимости делятся на более мелкие объекты. Перед началом работы желательно разделить всю систему на отдельные смысловые блоки хотя бы мысленно. Часто хватает выделения всего двух уровней (пакеты и классы). Несмотря на свою очевидность, данная мысль не является такой банальной, как кажется на первый взгляд. В качестве примера можно привести такой распространенный архитектурный шаблон, как "Модель-Вид-Контроллер", также известный как MVC. На первом уровне можно разместить самые крупные составные части. В качестве примера можно привести следующее: пользовательский интерфейс, работа с базой данных, установление линии связи с определенным объектом. А уже далее создавать классы по надобности. Но не нужно слишком усердствовать.

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

Функциональная декомпозиция

Деление на модули производится, основываясь на задачах, которые преследуются системой. При этом основную можно, как правило, разбить на несколько меньших по размеру. В этом случае необходимо следить, чтобы они могли выполняться/решаться независимо друг от друга. Исходя из этого, желательно, чтобы модуль отвечал за решение определенной части задачи и выполнял необходимую для этого функцию. Кроме того, следует озаботиться поступлением всех необходимых для успешного функционирования данных. Желательно добиваться наличия результата в условиях отсутствия помощи других модулей, только используя свои входящие данные. Что из этого выплывает? Под модулем понимается не какой-то произвольный кусок кода, а полноценная программная единица, являющаяся функционально осмысленной и законченной.

Комбинированная декомпозиция

Здесь рассматривается то, насколько модули фокусируются на решении поставленных задач. Здесь можно выделить комбинацию двух моментов:

  1. Высокая сопряженность. Этот параметр говорит о том, что модуль сфокусирован на одной узкой проблеме. Сопряженность достигается только в этом случае. Если же он выполняет разнородные функции и не связанные между собой обязанности, то это говорит о наличии существенных проблем.
  2. Слабая связанность. Этот параметр говорит о том, что отдельные модули, из которых строится система, независимы. Как допустимая, но малоприятная альтернатива – слабо связанные между собой. Но при этом они должны иметь возможности для взаимодействия.

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

В заключение

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

Комментарии