Summary - JohnKhandygo/EM GitHub Wiki

Введение

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

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

В качестве системы рассмотрим систему управлению персоналом, позволяющую автоматизировать некоторые аспекты повседневной деятельности персонала компании.

1. Роли

Разрабатываемая в рамках данной работы система оперирует тремя ролями со следующими интересами:

  • Работник
    • Резервировать время своего отсутствия в офисе.
    • Просматривать/изменять собственный рабочий план.
  • Менеджер
    • Имеет те же интересы, что и работник.
    • Просматривать информацию о рабочих, которые закреплены за ним.
    • Одобрять/отклонять запросы рабочих, которые закреплены за ним.
    • Выписывать премию любому из работников, которые закреплены за ним.
  • Бухгалтер
    • Имеет те же интересы, что и работник.
    • Одобрять/отклонять премию, выписанную работнику.

2. Варианты использования

Варианты использования системы описаны на UML диаграмме ниже. Диаграмма вариантов использования системы

3. Бизнес процессы

Ниже представлен список бизнес процессов, представленных в системе:

Запрос на предоставление отпуска

  1. Пользователь системы выбирает желаемый период отпуска.
  2. Если менеджер не имеет вышестоящего начальника, то запрос автоматически подтверждается системой. В противном случае см. пункт 3.
  3. Запрос поступает менеджеру, за которым закреплен работник.
  4. Менеджер принимает или отклоняет запрос пользователя на предоставление отпуска в указанный период.
  5. В случае утверждения отпуска, соответствующая запись появляется в рабочем плане работника.

Премирование работника

  1. Менеджер формирует запрос на выплату премии работнику, который закреплен за ним.
  2. Запрос поступает бухгалтеру, за которым закреплен данный работник.
  3. Бухгалтер утверждает или отклоняет запрос на выплату премии.
  4. В случае утверждения премии, соответствующая запись появляется в списке премиальных выплат работника.

Указание времени отсутствия

  1. Работник может указать период собственного отсутствия по какой-либо причине.
  2. Данное действие не требует подтверждения со стороны --- соответствующая запись сразу же размещается в рабочем плане работника.
  3. Работник может удалить любую такую запись из своего собственного рабочего плана.

4. Статическая модель системы

Статическая модель системы представлена в виде двух диаграмм классов для пакетов core (ядро) и bl (бизнес логика).

Доменная модель приложения

Сервисный уровень

5. Динамическая модель системы

Динамическая модель системы представлена в виде трех диаграмм, суммарно описывающих процесс премирования некоторого работника.

Запрос на выплату премии

Утверждение премии

Отклонение запроса

6. Проектирование слоя бизнес логики

В качестве основного шаблона слоя бизнес логики было решено использовать шаблон сервисов в силу того, что:

  • Сервис инкапсулирует в себе все зависимости, которые имеют отношение непосредственно к бизнес логике.
  • Для удобства тестирования: сервис обладает минимальным набором вспомогательных средств, необходимых для работы слоя бизнес логики (например, база данных). Каждый объект доменной области обладает своим собственным сервисом. Таким образом, можно считать, что сервис определяет варианты допустимых действий над объектом бизнес логики.

7. Реализация слоя бизнес логики

Классы, реализующие слой бизнес-логики размещены в пакете bl. В некотором роде каждый сервис представляет собой пример паттерна фасад: основная его роль в обеспечении удобного доступа к необходимой функциональности для других слоев.

Классы, реализующие слой бизнес логики могут быть найдены в пакете

8. Проектирование слоя источника данных

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

9. Реализация слоя источников данных

Для реализации слоя источников хранения было решено использовать стандарт JPA 2.0 в комбинации с reflection API для java. Такой подход позволил реализовать мапперы данных в единственном виде, хоть и с некоторыми ограничениями. Для отделения сущностей ядра от сущностей уровня хранения каждый класс уровня ядра имеет близнеца на уровне хранения данных. Здесь присутствует одностороння зависимость сущностей уровня хранения от сущностей уровня ядра. Это значит, что, например, смена схемы хранения повлечет за собой лишь изменение сущностей уровня хранения данных. Эти изменения не затронут ядро и слой бизнес логики до тех пор, пока существует биективное отображение между сущностями на обоих уровнях.

Классы, реализующие слой хранения данных могут быть найдены в пакете

Описание схемы хранения представлено здесь

10. Проектирование сервисного слоя и слоя представления

На этапе написания уровня доступа к приложению решено было использовать web клиент. Коммуникацию между клиентом и сервером было решено обеспечивать через REST-интерфейс.

11. Реализация слоя представления

Реализации REST-интерфейса заключается в "оборачивании" сервисов из слоя бизнес логики в класс: каждый метод сервиса получает близнеца на уровне представления для обеспечения доступа по протоколу http/https. Основная роль классов-ресурсов, таким образом, заключается в преобразовании формата данных, понятного клиенту, в формат, понятный приложению и наоборот. Здесь ситуация совершенно аналогична ситуации с сущностями на уровне хранения данных.

Классы, реализующие слой представления могут быть найдены в пакете

Ниже представлены примеры графического интерфейса приложения.

Страница авторизации

Страница авторизации

Страница внешнего сервиса (новости)

Страница внешнего сервиса

Заключение

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

  • Разделение функциональности: каждый слой отвечает только за одну область оперирования данными, как то: представление, манипулирование, персистентность.
  • Разделение сущностей: каждый слой оперирует своими представлениями, переферийные уровни отвечают за преобразование данных из/в формат(а) с низлежащих уровней.

Также в рамках данной работы был рзрботан внешний сервис и осуществлена его интеграция с основной системой.