Реализация хранилища #
Доработайте приложение для работы с треугольниками так, чтобы оно использовало хранилище для хранения данных. Хранилищу следует использовать структурированный формат хранения, JSON или другой стандарт, при сохранении их на жёсткий диск.
Для сохранении информации о конкретном треугольнике следует сохранять только стороны треугольника, т.е. минимально необходимую информацию.
Краткий подход к реализации #
Создание хранилища #
- Убедитесь, что в конфигурации сборки приложения, 
build.gradle, указана зависимость от модуля сериализации данных в JSON.implementation group: "org.http4k", name: "http4k-format-jackson", version: "4.25.8.0". Версия зависимости должна совпадать с версиями других компонентов http4k. - Создайте класс хранилища, 
Store. Он определяется путём к JSON-документу на жёстком диске. - В классе определите метод для сохранения данных. Метод должен формировать JSON-строку и записывать её в файл. В настоящий момент добавьте туда корневой элемент — пустой JSON-объект.
 - В классе 
Storeсоздайте полеsaveStore, в котором разместите объект потока Thread. Используйте методthread, предоставляемый стандартной библиотекой языка Kotlin.- Данный поток не должен запускаться автоматически.
 - Внутри блока, определяющего работу потока, вызовите метод сохранения.
 
 - Создайте объект класса 
Storeв функцииmain. Добавьте вызов потока сохранения хранилища с помощью метода addShutdownHook класса Runtime. - Запустите и остановите приложение. Если вы всё сделали корректно, то при остановке приложения JSON-документ на жёстком диске должен быть создан.
 
Описание репозитория треугольников #
- Создайте класс 
TriangleRepositoryв рамках пакетаdomain. Данный класс должен:- Инициализироваться списком треугольников.
 - Предоставлять метод 
asJsonObjectилиtoJson, которые будут предоставлять данные в формате классов, описывающих узлы JsonNode. 
 - Метод JsonNode должен возвращать следующую структуру данных в виде Json элементов:
{ "counter": 1, "triangles": [] } - Создайте объект репозитория треугольников в качестве свойства класса хранилища.
 - Используйте созданный метод по преобразованию репозитория треугольника в объект JsonNode. Сохраните результат внутри объекта с ключом 
triangles. - Запустите и остановите приложение.
 - В выходном файле должен быть сохранён документ со следующим содержимым:
{ "triangles": { "counter": 1, "triangles": [] } } 
Сериализация треугольника #
- В классе треугольник добавьте метод по его преобразованию в объект JsonNode.
 - Данный метод должен сохранять длины всех сторон. Предлагается следующая структура:
{ "sideA": 15.5, "sideB": 10.0, "sideC": 13.5 } - Используйте данный метод при формировании JSON-документа, описывающего состояние репозитория. Сохраняйте узлы, описывающие треугольники, внутри массива 
triangles. - Инициализируйте репозиторий при создании списком треугольников. Достаточно добавить пару треугольников.
 - Выполните запуск и остановку приложения.
 - В выходном файле, описывающим состояние, должно быть следующая структура:
{ "triangles": { "counter": 1, "triangles": [ { "sideA": 3, "sideB": 4, "sideC": 5 }, { "sideA": 10, "sideB": 10, "sideC": 3 } ] } } 
Уникальная идентификация треугольника #
- В классе треугольник добавьте поле 
id: Int, которое должно быть уникальным среди всех треугольников внутри репозитория. - Внутри репозитория треугольников организуйте хранение данных в изменяемом словаре (MutableMap), в котором ключами являются идентификаторы треугольников, а значением являются объекты треугольника. Изначальный список можно преобразовать к словарю с помощью функции associateBy.
 - В рамках репозитория необходимо обеспечить инициализацию поля 
counterтаким образом, чтобы оно содержало следующее значение идентификатора. Возможно реализовать стратегию двумя способами:- Передать корректное значение в качестве аргумента репозиторию.
 - Вычислить на основании переданных данных.
 
 - При добавлении нового элемента в репозиторий необходимо обеспечить проверку уникальности добавляемых элементов по идентификатору. Возможны следующие стратегии:
- Выбрасывание исключения при добавлении элемента.
 - Установление уникального идентификатора при добавлении нового элемента. В рамках данного подхода необходимо взять очередное значение из счётчика, поля 
counter, и использовать его при добавлении в словарь треугольников. 
 - Реализуйте функцию по добавлению нового элемента в репозиторий треугольников.
 
Выполнение запроса к репозиторию #
- В репозитории реализуйте метод для получения подмножества треугольников в зависимости от страницы. Функция должна принимать в качестве аргумента номер страницы и возвращать список из треугольников, удовлетворяющий запросу.
- Если номер страницы не входит в допустимые границы, то необходимо возвращать пустой список.
 - Обратите внимание на последнюю страницу - в ней скорее всего недостаточно элементов для заполнения всей страницы.
 
 - В репозитории реализуйте метод для получения треугольника по идентификатору.
 - Используйте созданные методы репозитория в обработчиках запроса от пользователя.
 - Удостоверьтесь, что после завершения работы приложения в JSON-документе сохраняются все данные из хранилища.
 
Инициализация хранилища из JSON-документа #
- В рамках хранилища реализуйте функцию, которая будет производить загрузку данных из JSON-документа на файловой системе. Данная функция должна считывать весь текст из документа и преобразовывать его к объектам JsonNode с помощью метода 
parse. - Полученный объект верхнего уровня необходимо разобрать внутри хранилища и передать извлечённое значение поля 
trianglesв функцию-инициализатор репозитория. - У репозитория следует объявить вспомогательный объект, 
companion object, который будет содержать функцию инициализации из JSON-объекта. - Такую же функцию следует реализовать и во вспомогательном объекте класса треугольника.
 - Вызовите функцию инициализации хранилища при создании объекта хранилища или из функции 
main. - Убедитесь, что при запуске приложения происходит чтение данных из JSON-объекта.
 
Соответствие кода статическому анализу #
Удостоверьтесь, что написанный код, удовлетворяет требованиям статического анализатора кода.