docs: replace data source task with csv student io task
This commit is contained in:
@@ -0,0 +1,324 @@
|
|||||||
|
# Техническое задание: чтение и дозапись `Student` в CSV
|
||||||
|
|
||||||
|
## Задача
|
||||||
|
|
||||||
|
Реализовать два независимых класса для работы с объектами `Student` в формате CSV:
|
||||||
|
|
||||||
|
- `StudentCsvWriter` — дозапись студентов в файл;
|
||||||
|
- `StudentCsvReader` — последовательное чтение студентов из файла.
|
||||||
|
|
||||||
|
Для работы с форматом CSV использовать готовую библиотеку для работы с CSV. Самостоятельно реализовывать парсинг CSV запрещено.
|
||||||
|
|
||||||
|
Оба класса должны принимать **абсолютный путь к файлу**.
|
||||||
|
|
||||||
|
Исключения `Student` и `StudentBuilder` не обрабатывать.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Формат CSV-файла
|
||||||
|
|
||||||
|
Первая строка файла должна содержать заголовок:
|
||||||
|
|
||||||
|
```text
|
||||||
|
groupNumber,averageGrade,recordBookNumber
|
||||||
|
```
|
||||||
|
|
||||||
|
Каждая следующая строка содержит данные одного студента:
|
||||||
|
|
||||||
|
```text
|
||||||
|
groupNumber,averageGrade,recordBookNumber
|
||||||
|
```
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```text
|
||||||
|
groupNumber,averageGrade,recordBookNumber
|
||||||
|
A12,4.5,10001
|
||||||
|
B07,3.8,10002
|
||||||
|
C25,4.9,10003
|
||||||
|
```
|
||||||
|
|
||||||
|
Для формирования и чтения CSV использовать стандартную библиотеку для работы с форматом CSV.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `StudentCsvWriter`
|
||||||
|
|
||||||
|
## Назначение
|
||||||
|
|
||||||
|
Дозаписывать одного студента в указанный CSV-файл.
|
||||||
|
|
||||||
|
## Контракт
|
||||||
|
|
||||||
|
Конструктор:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public StudentCsvWriter(String absoluteFilePath)
|
||||||
|
```
|
||||||
|
|
||||||
|
Метод:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public void write(Student student) throws IOException
|
||||||
|
```
|
||||||
|
|
||||||
|
### Требования
|
||||||
|
|
||||||
|
1. Метод принимает одного `Student`.
|
||||||
|
2. Запись выполняется в режиме добавления.
|
||||||
|
3. Существующие записи не изменяются.
|
||||||
|
4. Если файл существует, заголовок повторно не записывается.
|
||||||
|
5. Если файл не существует, необходимо создать файл.
|
||||||
|
6. При создании нового файла имя должно соответствовать формату:
|
||||||
|
|
||||||
|
```text
|
||||||
|
students-yyyy-MM-dd-HH-mm.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
Например:
|
||||||
|
|
||||||
|
```text
|
||||||
|
students-2026-08-28-20-45.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Новый файл создаётся в директории, указанной абсолютным путём.
|
||||||
|
2. При создании нового файла сначала записывается заголовок.
|
||||||
|
3. При успешной записи метод завершается без исключения.
|
||||||
|
4. Метод не возвращает значение.
|
||||||
|
5. Исключения, связанные с записью файла, не обрабатывать внутри метода — они должны передаваться вызывающему коду.
|
||||||
|
6. Исключения `Student` и `StudentBuilder` также не обрабатывать.
|
||||||
|
|
||||||
|
## Невозможность записи
|
||||||
|
|
||||||
|
Если студент не может быть записан, например:
|
||||||
|
|
||||||
|
- отсутствуют права на запись;
|
||||||
|
- невозможно создать файл;
|
||||||
|
- файл недоступен;
|
||||||
|
- произошла ошибка файловой системы;
|
||||||
|
|
||||||
|
метод должен выбросить соответствующее исключение, например `IOException`.
|
||||||
|
|
||||||
|
Запись не должна возвращать специальное значение вроде `0` для обозначения ошибки.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# `StudentCsvReader`
|
||||||
|
|
||||||
|
## Назначение
|
||||||
|
|
||||||
|
Последовательно читать студентов из CSV-файла.
|
||||||
|
|
||||||
|
## Контракт
|
||||||
|
|
||||||
|
Класс должен реализовывать:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Iterator<Student>
|
||||||
|
```
|
||||||
|
|
||||||
|
Конструктор:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public StudentCsvReader(String absoluteFilePath)
|
||||||
|
```
|
||||||
|
|
||||||
|
Методы:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public boolean hasNext()
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
public Student next()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Требования к `hasNext()`
|
||||||
|
|
||||||
|
1. Проверяет наличие следующей записи `Student`.
|
||||||
|
2. Заголовок CSV не считается записью.
|
||||||
|
3. Повторный вызов `hasNext()` не должен пропускать следующую запись.
|
||||||
|
4. После окончания файла метод возвращает `false`.
|
||||||
|
|
||||||
|
### Требования к `next()`
|
||||||
|
|
||||||
|
1. Возвращает следующего `Student`.
|
||||||
|
2. `Student` создаётся через существующий `StudentBuilder`.
|
||||||
|
3. При отсутствии следующего элемента выбрасывается:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NoSuchElementException
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Весь файл не должен предварительно загружаться в коллекцию.
|
||||||
|
|
||||||
|
## Невозможность прочитать студента
|
||||||
|
|
||||||
|
Если следующую запись невозможно прочитать или преобразовать в `Student`, например:
|
||||||
|
|
||||||
|
- некорректный формат CSV;
|
||||||
|
- отсутствует обязательное поле;
|
||||||
|
- значение невозможно преобразовать в нужный тип;
|
||||||
|
- данные не проходят валидацию `Student`;
|
||||||
|
|
||||||
|
исключение должно передаваться вызывающему коду.
|
||||||
|
|
||||||
|
Исключения `Student` и `StudentBuilder` **не перехватывать и не обрабатывать**.
|
||||||
|
|
||||||
|
Некорректные записи не должны молча пропускаться.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Общие требования
|
||||||
|
|
||||||
|
1. Оба класса принимают абсолютный путь к файлу.
|
||||||
|
2. Использовать готовую библиотеку для работы с CSV.
|
||||||
|
3. Не реализовывать собственный CSV-парсер.
|
||||||
|
4. Не использовать стандартные коллекции Java как основное хранилище студентов.
|
||||||
|
5. Не дублировать в этих классах валидацию `Student`.
|
||||||
|
6. Не дублировать логику создания `Student` вне `StudentBuilder`.
|
||||||
|
7. `StudentCsvWriter` отвечает только за запись.
|
||||||
|
8. `StudentCsvReader` отвечает только за чтение.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Примеры тестов
|
||||||
|
|
||||||
|
## `StudentCsvWriter`
|
||||||
|
|
||||||
|
### Создание нового файла
|
||||||
|
|
||||||
|
Передать путь к несуществующему файлу и вызвать:
|
||||||
|
|
||||||
|
```java
|
||||||
|
writer.write(student);
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить:
|
||||||
|
|
||||||
|
- файл создан;
|
||||||
|
- имя соответствует `students-yyyy-MM-dd-HH-mm.csv`;
|
||||||
|
- присутствует заголовок;
|
||||||
|
- студент записан;
|
||||||
|
- метод завершился без исключения.
|
||||||
|
|
||||||
|
### Дозапись
|
||||||
|
|
||||||
|
Создать файл с одним студентом и выполнить:
|
||||||
|
|
||||||
|
```java
|
||||||
|
writer.write(student2);
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить, что:
|
||||||
|
|
||||||
|
- первая запись сохранилась;
|
||||||
|
- `student2` добавлен в конец;
|
||||||
|
- заголовок присутствует только один раз.
|
||||||
|
|
||||||
|
### Несколько последовательных записей
|
||||||
|
|
||||||
|
```java
|
||||||
|
writer.write(student1);
|
||||||
|
writer.write(student2);
|
||||||
|
writer.write(student3);
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить наличие трёх записей в правильном порядке.
|
||||||
|
|
||||||
|
### Невозможность записи
|
||||||
|
|
||||||
|
Передать путь, по которому невозможно создать или открыть файл для записи.
|
||||||
|
|
||||||
|
Проверить, что `write()` выбрасывает `IOException`.
|
||||||
|
|
||||||
|
Не проверять специальное возвращаемое значение — метод ничего не возвращает.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `StudentCsvReader`
|
||||||
|
|
||||||
|
### Чтение корректного файла
|
||||||
|
|
||||||
|
Для файла:
|
||||||
|
|
||||||
|
```text
|
||||||
|
groupNumber,averageGrade,recordBookNumber
|
||||||
|
A12,4.5,10001
|
||||||
|
B07,3.8,10002
|
||||||
|
C25,4.9,10003
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить:
|
||||||
|
|
||||||
|
- `hasNext()` возвращает `true` до последнего студента;
|
||||||
|
- `next()` возвращает студентов в правильном порядке;
|
||||||
|
- после последнего студента `hasNext()` возвращает `false`.
|
||||||
|
|
||||||
|
### Повторный вызов `hasNext()`
|
||||||
|
|
||||||
|
```java
|
||||||
|
reader.hasNext();
|
||||||
|
reader.hasNext();
|
||||||
|
Student student = reader.next();
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить, что первый студент не был пропущен.
|
||||||
|
|
||||||
|
### `next()` после окончания файла
|
||||||
|
|
||||||
|
После чтения всех студентов вызвать:
|
||||||
|
|
||||||
|
```java
|
||||||
|
reader.next();
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить выброс:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NoSuchElementException
|
||||||
|
```
|
||||||
|
|
||||||
|
### Некорректная запись
|
||||||
|
|
||||||
|
Передать файл:
|
||||||
|
|
||||||
|
```text
|
||||||
|
groupNumber,averageGrade,recordBookNumber
|
||||||
|
A12,4.5,10001
|
||||||
|
INVALID
|
||||||
|
C25,4.9,10003
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить, что ошибка при чтении некорректной записи передаётся вызывающему коду.
|
||||||
|
|
||||||
|
### Некорректные данные `Student`
|
||||||
|
|
||||||
|
Передать данные, нарушающие ограничения `Student`.
|
||||||
|
|
||||||
|
Проверить, что исключение от `Student` или `StudentBuilder` выходит наружу и не перехватывается `StudentCsvReader`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Названия файлов
|
||||||
|
|
||||||
|
```text
|
||||||
|
StudentCsvWriter.java
|
||||||
|
StudentCsvReader.java
|
||||||
|
```
|
||||||
|
|
||||||
|
# Git
|
||||||
|
|
||||||
|
Название ветки:
|
||||||
|
|
||||||
|
```text
|
||||||
|
feature/csv-student-io
|
||||||
|
```
|
||||||
|
|
||||||
|
Conventional Commit:
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat: add csv student reader and writer
|
||||||
|
```
|
||||||
@@ -1,399 +0,0 @@
|
|||||||
# Техническое задание: источники данных
|
|
||||||
|
|
||||||
## Задача
|
|
||||||
|
|
||||||
Реализовать три независимых источника данных для формирования `MyList<Student>`:
|
|
||||||
|
|
||||||
- `ManualDataSource`;
|
|
||||||
- `RandomDataSource`;
|
|
||||||
- `FileDataSource`.
|
|
||||||
|
|
||||||
Все источники должны формировать только валидные объекты `Student`.
|
|
||||||
|
|
||||||
Класс `Student` содержит:
|
|
||||||
|
|
||||||
```java
|
|
||||||
private final String groupNumber;
|
|
||||||
private final double averageGrade;
|
|
||||||
private final String recordBookNumber;
|
|
||||||
```
|
|
||||||
|
|
||||||
Создание объектов `Student` выполнять через `StudentBuilder`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Общий контракт
|
|
||||||
|
|
||||||
Создать интерфейс `DataSource`:
|
|
||||||
|
|
||||||
```java
|
|
||||||
public interface DataSource {
|
|
||||||
|
|
||||||
MyList<Student> create();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Источник данных не должен самостоятельно получать данные от пользователя.
|
|
||||||
|
|
||||||
Все необходимые входные значения должны передаваться извне.
|
|
||||||
|
|
||||||
Результатом работы каждого источника является `MyList<Student>`.
|
|
||||||
|
|
||||||
Стандартные `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<Student>`.
|
|
||||||
|
|
||||||
Рекомендуемый метод для передачи одного объекта:
|
|
||||||
|
|
||||||
```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<Student> 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<Student>`.
|
|
||||||
7. Вернуть коллекцию заданного размера.
|
|
||||||
|
|
||||||
Минимальное и максимальное значения включаются в диапазон генерации.
|
|
||||||
|
|
||||||
`RandomDataSource` не должен самостоятельно получать или отображать параметры генерации.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# `FileDataSource`
|
|
||||||
|
|
||||||
## Назначение
|
|
||||||
|
|
||||||
Создавать `MyList<Student>` на основании содержимого файла.
|
|
||||||
|
|
||||||
## Входные данные
|
|
||||||
|
|
||||||
Передаётся **абсолютный путь к файлу**.
|
|
||||||
|
|
||||||
Относительный путь не является входным параметром `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<Student>`.
|
|
||||||
7. Пропустить некорректную запись и продолжить обработку остальных.
|
|
||||||
8. При невозможности открыть файл сообщить об ошибке.
|
|
||||||
9. Вернуть сформированную `MyList<Student>`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Общие требования
|
|
||||||
|
|
||||||
1. Все источники должны создавать `Student` только через `StudentBuilder`.
|
|
||||||
2. Источник данных не должен самостоятельно вводить данные.
|
|
||||||
3. Источник данных не должен зависеть от интерфейса пользователя.
|
|
||||||
4. Источник данных не должен содержать логику сортировки.
|
|
||||||
5. Результат хранить только в `MyList<Student>`.
|
|
||||||
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<Student> 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
|
|
||||||
ManualDataSource.java
|
|
||||||
RandomDataSource.java
|
|
||||||
FileDataSource.java
|
|
||||||
```
|
|
||||||
|
|
||||||
Допускается создание вспомогательных классов для чтения файла и генерации случайных значений.
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
# Дополнение к техническому заданию: изменение типа `recordBookNumber`
|
|
||||||
|
|
||||||
Данное дополнение имеет **приоритет над основным ТЗ `DataSource.md`**.
|
|
||||||
|
|
||||||
## Изменение модели `Student`
|
|
||||||
|
|
||||||
Поле:
|
|
||||||
|
|
||||||
```java
|
|
||||||
private final String recordBookNumber;
|
|
||||||
```
|
|
||||||
|
|
||||||
заменено на:
|
|
||||||
|
|
||||||
```java
|
|
||||||
private final int recordBookNumber;
|
|
||||||
```
|
|
||||||
|
|
||||||
Метод:
|
|
||||||
|
|
||||||
```java
|
|
||||||
getRecordBookNumber()
|
|
||||||
```
|
|
||||||
|
|
||||||
возвращает `int`.
|
|
||||||
|
|
||||||
## Требования к `DataSource`
|
|
||||||
|
|
||||||
Во всех реализациях источников данных необходимо учитывать новый тип `recordBookNumber`.
|
|
||||||
|
|
||||||
### `ManualDataSource`
|
|
||||||
|
|
||||||
`recordBookNumber` должен передаваться как `int`:
|
|
||||||
|
|
||||||
```java
|
|
||||||
setStudent(
|
|
||||||
int index,
|
|
||||||
String groupNumber,
|
|
||||||
double averageGrade,
|
|
||||||
int recordBookNumber
|
|
||||||
);
|
|
||||||
```
|
|
||||||
|
|
||||||
Строковое значение номера зачётной книжки больше не используется.
|
|
||||||
|
|
||||||
### `RandomDataSource`
|
|
||||||
|
|
||||||
Для `recordBookNumber` необходимо задавать и генерировать **числовой диапазон**:
|
|
||||||
|
|
||||||
```text
|
|
||||||
минимальное значение — int
|
|
||||||
максимальное значение — int
|
|
||||||
```
|
|
||||||
|
|
||||||
Генерируемое значение должно быть целым числом и соответствовать ограничениям `Student`.
|
|
||||||
|
|
||||||
### `FileDataSource`
|
|
||||||
|
|
||||||
В файле `recordBookNumber` должен записываться как целое число.
|
|
||||||
|
|
||||||
Формат записи:
|
|
||||||
|
|
||||||
```text
|
|
||||||
groupNumber;averageGrade;recordBookNumber
|
|
||||||
```
|
|
||||||
|
|
||||||
Пример:
|
|
||||||
|
|
||||||
```text
|
|
||||||
A12;4.75;12345
|
|
||||||
B32;3.80;12346
|
|
||||||
C17;4.20;12347
|
|
||||||
```
|
|
||||||
|
|
||||||
При чтении значение необходимо преобразовать в `int` до создания `Student`.
|
|
||||||
|
|
||||||
## Приоритет
|
|
||||||
|
|
||||||
При противоречии между данным дополнением и основным `DataSource.md` использовать требования этого дополнения.
|
|
||||||
|
|
||||||
Все остальные требования основного технического задания остаются без изменений.
|
|
||||||
Reference in New Issue
Block a user