From 57868a33a29ab4232f22f00669185484ba24ef85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BE=D0=BB=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=93=D0=B5?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D0=BD?= Date: Tue, 25 Aug 2026 23:41:58 +0400 Subject: [PATCH] docs: add student update task --- docs/tasks/StudentUpdate.md | 326 ++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 docs/tasks/StudentUpdate.md diff --git a/docs/tasks/StudentUpdate.md b/docs/tasks/StudentUpdate.md new file mode 100644 index 0000000..e3db385 --- /dev/null +++ b/docs/tasks/StudentUpdate.md @@ -0,0 +1,326 @@ +# Техническое задание: обновление `Student` + +## Задача + +Обновить класс `Student` и связанный с ним код в соответствии с новой моделью данных и требованиями к неизменяемости объекта. + +Текущая реализация содержит: + +```java +private final String groupNumber; +private final double averageGrade; +private final String recordBookNumber; +``` + +Необходимо изменить тип `recordBookNumber` и добавить методы создания изменённых копий `Student`. + +## Изменения в `Student` + +### 1. Изменить тип `recordBookNumber` + +Поле: + +```java +private final String recordBookNumber; +``` + +заменить на: + +```java +private final int recordBookNumber; +``` + +Метод: + +```java +getRecordBookNumber() +``` + +должен возвращать `int`. + +Все проверки, `equals()`, `hashCode()` и `toString()` должны быть адаптированы под новый тип. + +### 2. Добавить бизнес-правило для `groupNumber` + +`groupNumber` должен соответствовать строго следующему формату: + +```text +<Заглавная буква латинского алфавита><2 цифры> +``` + +Регулярное выражение: + +```text +^[A-Z][0-9]{2}$ +``` + +Допустимые значения: + +```text +A12 +B32 +Z00 +``` + +Недопустимые значения: + +```text +а12 +a12 +A1 +A123 +AA1 +а1А +аа!!а123 +23фи!12 +№№###*() +``` + +Проверка должна выполняться при создании `Student`. + +`Student` не может существовать с некорректным `groupNumber`. + +### 3. Проверить `averageGrade` + +Сохранить правило: + +```text +0.0 <= averageGrade <= 5.0 +``` + +Значения `0.0` и `5.0` допустимы. + +### 4. Проверить `recordBookNumber` + +После преобразования в `int` установить бизнес-правило: + +```text +recordBookNumber > 0 +``` + +Значение `0` и отрицательные значения считаются недопустимыми. + +--- + +# Методы `with...()` + +Добавить методы, возвращающие **новый объект `Student`**, не изменяя текущий объект. + +Необходимо реализовать: + +```java +withGroupNumber(String groupNumber) +withAverageGrade(double averageGrade) +withRecordBookNumber(int recordBookNumber) +``` + +Каждый метод должен: + +1. Сохранять исходный объект без изменений. +2. Изменять только указанное поле в новом объекте. +3. Сохранять остальные поля исходного объекта. +4. Повторно применять все правила валидации. +5. Возвращать новый валидный объект `Student`. + +Пример: + +```java +Student updated = student.withAverageGrade(4.8); +``` + +После выполнения: + +```text +student.getAverageGrade() == прежнее значение +updated.getAverageGrade() == 4.8 +``` + +Если новое значение невалидно, метод должен выбросить исключение, а исходный объект не должен измениться. + +--- + +# `StudentBuilder` + +Обновить существующий `StudentBuilder` в соответствии с новой моделью `Student`. + +Методы должны соответствовать типам: + +```java +setGroupNumber(String groupNumber) +setAverageGrade(double averageGrade) +setRecordBookNumber(int recordBookNumber) +``` + +`build()` должен создавать только валидный `Student`. + +Все новые правила валидации должны применяться при создании объекта через `StudentBuilder`. + +--- + +# Обновление зависимого кода + +Найти и обновить весь код, использующий `Student` и изменяемые методы или типы. + +В частности, обновить: + +- `Comparator`; +- сортировки; +- источники данных; +- тестовые классы; +- создание `Student`; +- `with...()`-операции; +- чтение и запись данных, если они используют `recordBookNumber`. + +Например, существующий: + +```java +implements Comparator +``` + +должен использовать актуальный метод: + +```java +getAverageGrade() +``` + +вместо ошибочного `getAvarageGrade()`. + +Компаратор `recordBookNumber` должен сравнивать значения как числа. + +Например: + +```java +Integer.compare( + s1.getRecordBookNumber(), + s2.getRecordBookNumber() +) +``` + +Все места, где `recordBookNumber` рассматривался как `String`, необходимо адаптировать к `int`. + +--- + +# Тесты + +Обновить существующий `StudentTest` с учётом новой модели. + +## Создание корректного `Student` + +Проверить создание объекта со значениями: + +```text +groupNumber = A12 +averageGrade = 4.5 +recordBookNumber = 12345 +``` + +Проверить корректность всех геттеров. + +## Проверка `groupNumber` + +Проверить успешное создание для: + +```text +A12 +B32 +Z00 +``` + +Проверить исключение для: + +```text +a12 +A1 +A123 +AA1 +а1А +аа!!а123 +23фи!12 +№№###*() +``` + +## Проверка `averageGrade` + +Проверить: + +```text +0.0 — допустимо +5.0 — допустимо +-1.0 — недопустимо +6.0 — недопустимо +``` + +## Проверка `recordBookNumber` + +Проверить: + +```text +1 — допустимо +12345 — допустимо +0 — недопустимо +-1 — недопустимо +``` + +## Тесты `with...()` + +### `withGroupNumber()` + +Проверить, что: + +- возвращается новый объект; +- `groupNumber` изменён; +- `averageGrade` не изменился; +- `recordBookNumber` не изменился; +- исходный `Student` остался прежним. + +### `withAverageGrade()` + +Проверить те же свойства для `averageGrade`. + +### `withRecordBookNumber()` + +Проверить те же свойства для `recordBookNumber`. + +### `with...()` с невалидным значением + +Для каждого метода передать некорректное значение. + +Проверить: + +- выбрасывается `IllegalArgumentException`; +- исходный объект не изменяется; +- не создаётся невалидный `Student`. + +## `equals()` и `hashCode()` + +Обновить существующие тесты с учётом `int recordBookNumber`. + +Проверить: + +- одинаковые студенты равны; +- одинаковые студенты имеют одинаковый `hashCode`; +- изменение любого поля создаёт отличающийся объект. + +## Результат + +Необходимо обновить: + +```text +Student.java +StudentBuilder.java +StudentTest.java +``` + +а также **все классы проекта, зависящие от изменённого интерфейса `Student`**, включая компараторы и другие реализации, использующие `recordBookNumber`, `groupNumber`, `averageGrade` или их геттеры. + +### Основной принцип + +`Student` должен оставаться единственной точкой истины для валидности данных: + +```text +StudentBuilder ──┐ + ├──> Student +with...() ───────┘ +``` + +Ни `Builder`, ни `with...()`, ни внешние классы не должны позволять создать невалидный объект.