diff --git a/docs/tasks/DataSource.md b/docs/tasks/DataSource.md index 3c42760..79a6c14 100644 --- a/docs/tasks/DataSource.md +++ b/docs/tasks/DataSource.md @@ -1,38 +1,393 @@ -# Техническое задание: заполнение коллекции +# Техническое задание: источники данных ## Задача -Реализовать разные способы заполнения `MyList` данными. +Реализовать три независимых источника данных для формирования `MyList`: -## Требования +- `ManualDataSource`; +- `RandomDataSource`; +- `FileDataSource`. -1. Создать интерфейс `DataSource` с методом: +Все источники должны формировать только валидные объекты `Student`. -```text -fill(int size) +Класс `Student` содержит: + +```java +private final String groupNumber; +private final double averageGrade; +private final String recordBookNumber; ``` -2. Реализовать три способа заполнения: +Создание объектов `Student` выполнять через `StudentBuilder`. - - `ManualDataSource` — ручной ввод; - - `RandomDataSource` — случайная генерация; - - `FileDataSource` — чтение из файла. +--- -3. Результатом работы каждого источника должна быть коллекция `MyList`. +# Общий контракт -4. Для создания объектов `Student` использовать `StudentBuilder`. +Создать интерфейс `DataSource`: -5. Все данные должны проходить валидацию средствами `Student`. +```java +public interface DataSource { -6. При ручном вводе некорректные данные не должны добавляться в коллекцию. + MyList create(); +} +``` -7. При чтении из файла некорректные строки должны обрабатываться без создания невалидных объектов `Student`. +Источник данных не должен самостоятельно получать данные от пользователя. -8. Размер коллекции должен задаваться пользователем и соблюдаться при заполнении. +Все необходимые входные значения должны передаваться извне. -9. Не использовать стандартные коллекции `List`, `ArrayList`, `LinkedList` для хранения результата. +Результатом работы каждого источника является `MyList`. -## Результат +Стандартные `List`, `ArrayList` и `LinkedList` для хранения результата не использовать. + +--- + +# `ManualDataSource` + +## Назначение + +Постепенно формировать коллекцию `Student` на основе значений, передаваемых извне для каждого отдельного объекта. + +## Входные данные одного объекта + +Для создания одного `Student` передаются: + +```text +groupNumber +averageGrade +recordBookNumber +``` + +Также передаётся `index` — позиция в коллекции, на которой должен находиться создаваемый объект. + +Размер результирующей коллекции задаётся заранее. + +## Контракт + +`ManualDataSource` должен: + +1. Принимать требуемый размер коллекции. +2. Принимать значения одного `Student`: + + - `groupNumber`; + - `averageGrade`; + - `recordBookNumber`. + +3. Принимать индекс, на котором должен находиться этот объект. +4. Создавать новый `Student` через `StudentBuilder`. +5. Добавлять созданный объект в нужную позицию коллекции. +6. Позволять повторно передавать данные для существующего индекса, заменяя объект на новый. +7. Проверять допустимость индекса. +8. Не изменять уже созданный объект `Student`. +9. Позволять получить текущее состояние коллекции для просмотра. +10. После заполнения вернуть сформированную `MyList`. + +Рекомендуемый метод для передачи одного объекта: + +```java +setStudent( + int index, + String groupNumber, + double averageGrade, + String recordBookNumber +) +``` + +Таким образом, пользовательский код может последовательно передать данные для всех элементов: + +```java +dataSource.setStudent(0, "101", 4.5, "10001"); +dataSource.setStudent(1, "102", 3.8, "10002"); +dataSource.setStudent(2, "101", 4.9, "10003"); +``` + +После заполнения: + +```java +MyList students = dataSource.create(); +``` + +### Изменение объекта + +Для изменения объекта повторно вызывается `setStudent(...)` с нужным индексом: + +```java +dataSource.setStudent(1, "105", 4.2, "10025"); +``` + +Объект на позиции `1` заменяется новым валидным `Student`. + +### Размер коллекции + +Если задан: + +```text +size = 5 +``` + +то для успешного создания коллекции должны быть заданы данные для всех пяти позиций: + +```text +0 +1 +2 +3 +4 +``` + +Порядок заполнения не обязан совпадать с порядком индексов: + +```java +dataSource.setStudent(3, "103", 4.1, "10004"); +dataSource.setStudent(0, "101", 4.5, "10001"); +dataSource.setStudent(4, "102", 3.9, "10005"); +dataSource.setStudent(1, "101", 4.8, "10002"); +dataSource.setStudent(2, "104", 3.7, "10003"); +``` + +После заполнения коллекция должна содержать ровно пять объектов в соответствии с указанными индексами. + +Если хотя бы одна позиция не заполнена, `create()` должен сообщить об ошибке и не возвращать неполную коллекцию. + +--- + +# `RandomDataSource` + +## Назначение + +Создавать заданное количество `Student` со случайными значениями в диапазонах, заданных извне. + +## Входные данные + +Передаются: + +```text +size +``` + +и диапазоны для каждого поля: + +```text +groupNumber: + minimum + maximum + +averageGrade: + minimum + maximum + +recordBookNumber: + minimum + maximum +``` + +## Контракт + +`RandomDataSource` должен: + +1. Принять размер создаваемой коллекции. +2. Принять минимальное и максимальное значение каждого поля. +3. Проверить корректность каждого диапазона. +4. Сгенерировать значения в заданных пределах. +5. Создать каждый объект через `StudentBuilder`. +6. Поместить объекты в `MyList`. +7. Вернуть коллекцию заданного размера. + +Минимальное и максимальное значения включаются в диапазон генерации. + +`RandomDataSource` не должен самостоятельно получать или отображать параметры генерации. + +--- + +# `FileDataSource` + +## Назначение + +Создавать `MyList` на основании содержимого файла. + +## Входные данные + +Передаётся **абсолютный путь к файлу**. + +Относительный путь не является входным параметром `FileDataSource`. + +Формат одной записи: + +```text +groupNumber;averageGrade;recordBookNumber +``` + +Пример: + +```text +101;4.75;123456 +102;3.80;123457 +103;4.20;123458 +``` + +## Контракт + +`FileDataSource` должен: + +1. Получить абсолютный путь к файлу. +2. Открыть файл. +3. Последовательно обработать его записи. +4. Разделить каждую запись на три значения. +5. Создать `Student` через `StudentBuilder`. +6. Добавить только валидные объекты в `MyList`. +7. Пропустить некорректную запись и продолжить обработку остальных. +8. При невозможности открыть файл сообщить об ошибке. +9. Вернуть сформированную `MyList`. + +--- + +# Общие требования + +1. Все источники должны создавать `Student` только через `StudentBuilder`. +2. Источник данных не должен самостоятельно вводить данные. +3. Источник данных не должен зависеть от интерфейса пользователя. +4. Источник данных не должен содержать логику сортировки. +5. Результат хранить только в `MyList`. +6. Невалидный `Student` не должен попасть в коллекцию. +7. Проверка корректности самого объекта выполняется средствами `Student`. +8. Для ручного заполнения изменение существующего `Student` выполнять заменой объекта, а не изменением его полей. + +--- + +# Примеры тестов + +## `ManualDataSource` + +### Заполнение всей коллекции + +Создать источник размера `3`: + +```java +ManualDataSource dataSource = new ManualDataSource(3); + +dataSource.setStudent(0, "101", 4.5, "10001"); +dataSource.setStudent(1, "102", 3.8, "10002"); +dataSource.setStudent(2, "103", 4.2, "10003"); + +MyList result = dataSource.create(); +``` + +Проверить: + +```text +result.size() == 3 +``` + +и соответствие каждого объекта своему индексу. + +### Заполнение в произвольном порядке + +```java +dataSource.setStudent(2, "103", 4.2, "10003"); +dataSource.setStudent(0, "101", 4.5, "10001"); +dataSource.setStudent(1, "102", 3.8, "10002"); +``` + +Проверить правильное расположение объектов. + +### Изменение объекта + +После заполнения: + +```java +dataSource.setStudent(1, "105", 4.9, "10025"); +``` + +Проверить, что изменился только объект с индексом `1`. + +### Незаданный индекс + +Для коллекции размера `3` вызвать: + +```java +dataSource.setStudent(3, ...); +``` + +Проверить выброс исключения. + +### Неполное заполнение + +Заполнить только две позиции из трёх и вызвать `create()`. + +Проверить, что неполная коллекция не возвращается. + +--- + +## `RandomDataSource` + +### Корректная генерация + +Задать размер `100` и допустимые диапазоны для всех трёх полей. + +Проверить: + +```text +result.size() == 100 +``` + +и нахождение каждого значения внутри заданного диапазона. + +### Граничный диапазон + +Задать одинаковые минимальное и максимальное значения. + +Проверить, что все сгенерированные значения соответствуют этому значению. + +### Некорректный диапазон + +Задать: + +```text +minimum > maximum +``` + +Проверить выброс исключения. + +--- + +## `FileDataSource` + +### Корректный файл + +Для файла: + +```text +101;4.75;123456 +102;3.80;123457 +103;4.20;123458 +``` + +проверить получение трёх корректных объектов. + +### Файл с некорректной записью + +```text +101;4.75;123456 +invalid;abc;123457 +103;4.20;123458 +``` + +Проверить, что в коллекцию попадают только две корректные записи. + +### Пустой файл + +Проверить получение пустой коллекции. + +### Несуществующий файл + +Передать путь к несуществующему файлу и проверить корректную обработку ошибки. + +--- + +# Результат + +Реализовать: ```text DataSource.java @@ -41,4 +396,4 @@ RandomDataSource.java FileDataSource.java ``` -Классы не должны содержать логику сортировки или пользовательского меню. +Допускается создание вспомогательных классов для чтения файла и генерации случайных значений.