JavaRush /Java блог /Java Developer /Часть 2. Поговорим немного об архитектуре ПО
Professor Hans Noodles
41 уровень

Часть 2. Поговорим немного об архитектуре ПО

Статья из группы Java Developer
Этот материал — часть цикла “Введение в Enterprise-разработку”. Первая часть о сети — здесь. Часть 2. Поговорим немного об архитектуре ПО - 1Архитектура программного обеспечения — структура, на базе которой создается приложение, взаимодействуют модули и компоненты всей программы. За создание хорошей архитектуры программисты взялись еще очень давно, поэтому неудивительно, что сейчас нам известно немало архитектурных шаблонов. Разбираться в них нужно: когда пишешь веб-приложение, проблема архитектуры становится острой, ведь в ней компонентов и модулей больше, чем в обычном приложении. Архитектурный шаблон — это уже придуманный способ решения какой-то задачи по проектированию программного обеспечения. Ты уже наверняка сталкивался с такими паттернами проектирования как фабричный метод (Factory Method), абстрактная фабрика (Abstract Factory), строитель (Builder), прототип (Prototype), одиночка (Singleton) и, возможно, другими. Они используются при простом написании кода, создании классов и планировании их взаимодействия. Архитектурные шаблоны задействуют на более высоком уровне абстракции — при планировании взаимодействия пользователя приложения с сервером, данными и другими компонентами проекта. Давай сразу рассмотрим некоторые шаблоны и то, как их использовать.

Клиент-серверная архитектура

Из названия складывается впечатление, что с этой темой все просто и понятно. Но давай уточним кое-какие моменты, чтобы приступив к изучению условного Спринга ты точно понимал, о чем идет речь. Допустим, ты написал чат, и вы с приятелем начинаете его использовать. Здесь возможен простой вариант — вы отправляете сообщение друг другу напрямую через интернет по IP-адресам, которые вы знаете: Часть 2. Поговорим немного об архитектуре ПО - 2Поначалу может показаться, что все отлично работает, пока не появляется еще один ваш друг с вопросом: “А почему вы не добавите меня в свой чат?”. И вот когда ты решаешь добавить общего друга в чат, ты сталкиваешься с архитектурной проблемой: каждому пользователю чата нужно обновить информацию о количестве пользователей, добавить IP-адрес нового юзера. А еще при отправке сообщения оно должно доставляться всем участникам. Это самые очевидные проблемы из тех, которые возникнут. Еще куча проблем будет спрятана в самом коде. Чтобы избежать их, нужно использовать сервер, который будет хранить всю информацию о пользователях, знать их адреса. Сообщение нужно будет отправить только на сервер. А он, в свою очередь, разошлет сообщение всем адресатам. Когда ты решишь добавить серверную часть в свой чат, ты начнешь строить клиент-серверную архитектуру.

Составляющие клиент-серверной архитектуры

Давай разберемся, что она представляет из себя. Клиент-серверная архитектура — шаблон проектирования, основа для создания веб-приложений. Данная архитектура состоит из трех компонентов: Часть 2. Поговорим немного об архитектуре ПО - 3
  1. Клиент — из названия становится понятно, что это пользователь сервиса (веб-приложения), который обращается к серверу для получения какой-то информации.

  2. Сервер — место, где располагается твое веб-приложение или его серверная часть. Он владеет необходимой информацией о пользователях или может ее запрашивать. Также при обращении клиента сервер возвращает ему запрашиваемую информацию.

  3. Сеть — все просто: обеспечивает обмен информацией между клиентом и сервером.

Сервер может обрабатывать огромное количество запросов от разных юзеров. То есть клиентов может быть много, а если им нужно обменяться информацией между собой, делать это придется через сервер. Таким образом, сервер получает еще одну дополнительную функцию — контроль трафика. Если речь идет о созданном нами многопользовательском чате, весь программный код будет состоять из двух модулей:
  • клиентского — содержит графический интерфейс для авторизации, отправки/получения сообщений;

  • серверного — веб-приложение, которое размещается на сервере и принимает сообщения от пользователей, обрабатывает их, а потом отправляет адресатам.

Часть 2. Поговорим немного об архитектуре ПО - 4Когда мы хотим посмотреть полезную (или не очень полезную) информацию в интернете, мы открываем браузер, в строке поиска вводим запрос, и в ответ получаем информацию от поисковика. В этой цепочке браузер — это наш клиент. Он отправляет запрос с информацией о том, что мы ищем, серверу. Сервер обрабатывает запрос, находит наиболее релевантные результаты, упаковывает их в понятный для браузера (клиента) формат и отправляет назад. В таких сложных сервисах как поисковики серверов может быть много. Например, сервер авторизации, сервер для поиска информации, сервер для формирования ответа. Но клиент об этом ничего не знает: для него сервер является чем-то единым. Клиент знает только о точке входа, то есть, адресе сервера, которому нужно отправить запрос. Вспомним о приложении, которое мы рассматривали в предыдущей части — для мониторинга средней температуры воздуха во всех странах в режиме реального времени. Его архитектура будет выглядеть примерно так: Часть 2. Поговорим немного об архитектуре ПО - 5Наше приложение располагается на сервере. Скажем, каждые пять секунд оно отправляет запросы на серверы локальных гидрометцентров, получает у них информацию о температуре в конкретной стране, сохраняет эту информацию. Когда клиент обращается к нам с запросом “посмотреть текущую температуру воздуха в мире”, мы возвращаем последнюю сохраненную информацию, рассортированную по странам. Таким образом наше приложение одновременно и сервер (когда обрабатывает запросы юзеров), и клиент (когда получает информацию у других серверов).
Важно: понятие сервер — не о конкретном компьютере, а о взаимоотношениях абонентов сети.
Простая клиент-серверная архитектура применяется очень редко и только для очень простых приложений. Для действительно больших и сложных проектов используются разные типы архитектур, с которыми ты еще познакомишься в будущем. Сейчас же давай рассмотрим модель, очень похожую на клиент-серверную.

Трехуровневая архитектура

Это архитектурный шаблон, в котором появляется третий участник — хранилище данных. При использовании этого шаблона, три уровня принято называть слоями: Часть 2. Поговорим немного об архитектуре ПО - 6
  1. Клиентский слой — интерфейс пользователя. Это может быть веб-браузер, которому отправляются HTML-страницы, или графическое приложение, написанное с помощью JavaFX. Главное, чтобы с его помощью пользователь мог отправлять запросы на сервер и обрабатывать его ответы.

  2. Слой логики — сервер, на котором происходит обработка запросов/ответов. Часто его еще называют серверным слоем. Также здесь происходят все логические операции: математические расчеты, операции с данными, обращения к другим сервисам или хранилищам данных.

  3. Слой данных — сервер баз данных: к нему обращается наш сервер. В этом слое сохраняется вся необходимая информация, которой пользуется приложение при работе.

Таким образом, наш сервер принимает на себя все обязательства по обращению к данным, не давая возможности юзеру обратиться к ним напрямую.

Преимущества трехуровневой архитектуры

Используя такую архитектуру, мы получаем немало плюсов, среди которых:
  1. Возможность построить защиту от SQL-инъекций — это атака на сервер, при которой передается SQL-код, и при выполнении этого кода злоумышленник может воздействовать на нашу базу данных.

  2. Разграничение данных, к которым мы хотим регулировать пользовательский доступ.

  3. Возможность модифицировать данные перед отправкой клиенту.

  4. Масштабируемость — возможность расширить наше приложение на несколько серверов, которые будут использовать одну и ту же базу данных.

  5. Меньшие требования к качеству соединения пользователя. Формируя ответ на сервере, мы часто берем из базы данных много различной информации, форматируем ее, оставляя только то, что нужно юзеру. Таким образом мы сокращаем объем информации, который отправим в качестве ответа клиенту.

Как часто нужно использовать архитектурные шаблоны?

Если ты знаком, скажем, с паттерном проектирования Фабричный метод, ты наверняка задумывался, когда его стоит использовать. Иногда трудно определиться, что делать: создать объект с помощью оператора new или использовав фабричный метод. Но со временем понимание приходит. С архитектурными шаблонами дела обстоят немного иначе. Enterprise-фреймворки рассчитаны на то, что программист с их помощью создает проект на основе какого-то общепринятого паттерна. Поэтому перед изучением Spring Framework тебе обязательно нужно понимать, что такое клиент-серверная архитектура, трехуровневая архитектура и MVC-архитектура. Не переживай: об MVC-архитектуре мы еще поговорим. Часть 1. Что нужно знать перед изучением Spring и JavaEE Часть 3. Протоколы HTTP/HTTPS Часть 4.Основы Maven Часть 5. Сервлеты. Пишем простое веб-приложение Часть 6. Контейнеры сервлетов Часть 7. Знакомство с паттерном MVC (Model-View-Controller) Часть 8. Пишем небольшое приложение на spring-boot
Комментарии (12)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Fl1s Уровень 51
18 апреля 2024
Великолепный цикл статей! Авторы курса решили сотворить финальный реверанс, перед тем как каждый из нас отправится в свой разработческий путь =]
Павел Уровень 35
26 ноября 2021
Пример простейшего TCP сервера и клиента, для java 10 и выше:

public class Server {
    public static void main(String[] args) {
        try (var listener = new ServerSocket(59090)) {
            System.out.println("The server is running...");
            while (true) {
                try (var socket = listener.accept()) {
                    var out = new PrintWriter(socket.getOutputStream(), true);
                    out.println("Hello, Net!");
                }catch (IOException ioe) {ioe.printStackTrace();}
            }
        }catch (IOException ioe) {ioe.printStackTrace();}
    }
}

public class Client {

    public static void main(String[] args) {

        try (var socket = new Socket("localhost", 59090);
            var in = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
            System.out.println("Server response: ");
            System.out.println(in.readLine());
        }catch (IOException ioe) {ioe.printStackTrace();}
    }
}
barracuda Уровень 41 Expert
11 апреля 2021
До чего ж я дошёл...
Anonymous #2413783 Уровень 36
28 декабря 2020
Присоединяюсь, отличная статья
Не ну это не серьезно Уровень 31 Expert
9 мая 2020
👏 прекрасная статья
Andrew Grini (AG) Уровень 17
11 февраля 2020
Отличный цикл статей, доступный для понимания и начинающим. Продолжайте и не останавливайтесь!
Vladimir Buchenkov Уровень 24
4 февраля 2020
Действительно хороший цикл статей, вдобавок можно порекомендовать только лекцию из cs50(во вкладке курсы есть этот курс) 6-го уровня с названием "Протокол TCP/IP и HTTP". Там хорошо обьясняется про запросы на базовом уровне.
Konstantin Уровень 20
4 февраля 2020
Хорошая статья, спасибо!
Юрий Уровень 31
4 февраля 2020
Спасибо за статью!!!!