Введение
Общественный пункт выдачи предоставляет реальные инструменты зарегистрированным участникам. Две дрели могут иметь одинаковое название, но относиться к разным выдачам. Инструмент на обслуживании должен оставаться недоступным, а вернуть выданный инструмент может только записанный заёмщик.
Вы закрепите эти правила в объекте Java, а затем воспользуетесь подготовленным небольшим циклом команд. В первой лабораторной работе изменения остаются в памяти; следующая учит их сохранять. Предполагается знакомство с классами, методами, закрытыми полями, списками и основами исключений Java. Авторская оценка времени на чтение и практику — 45 минут.
Выдайте инструмент, не потеряв его идентичность
На этом шаге вы выполните обычную выдачу, прочитаете подготовленный объект и добавите небольшое правило, защищающее его от повторной выдачи.
Откройте вкладку Terminal. cd выбирает папку проекта; все последующие команды оболочки в этой работе выполняются из неё. Если строка с опечаткой ещё не выполнена, нажмите Ctrl+U, чтобы очистить её, и введите заново. При сообщении «file not found» повторите этот cd, а не сбрасывайте окружение.
cd /home/labex/project/tool-library
Подготовленное приложение уже компилируется. javac — компилятор Java, -encoding UTF-8 задаёт кодировку исходного текста, -d out помещает скомпилированные классы в out, а *.java выбирает исходные файлы Java в этой папке.
javac -encoding UTF-8 -d out *.java
Успешная компиляция ничего не выводит. После редактирования добивайтесь успешной компиляции перед каждым запуском, иначе Java может запустить старые классы. java запускает программу, -Dfile.encoding=UTF-8 задаёт её текстовую кодировку, -cp out выбирает скомпилированные классы, а Desk — входной класс. desk.tsv предоставляет записи; --memory отключает сохранение в этой работе.
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Теперь вы внутри программы пункта выдачи, а не в оболочке. Вводите каждую строку и нажимайте Enter:
borrow A11 M01
list
quit
Ожидается Accepted: A11 BORROWED M01. A12 — другая дрель (Drill), которая остаётся AVAILABLE: ID идентифицирует физический инструмент, а название может повторяться. quit возвращает в оболочку. Обычная выдача работает до исправления, но код пока не защищает её от повторной выдачи. Поскольку этот запуск использовал --memory, исходный файл не изменился и следующий запуск начнётся с исходного состояния.
Прочитайте подготовленный исходный код с помощью cat: команда показывает файл, не редактируя его.
cat Tool.java
Инструмент хранит стабильный id, отображаемое имя name, состояние state, заёмщика borrower и примечание note. enum имеет фиксированный набор именованных значений: AVAILABLE означает, что инструмент ни у кого не находится, BORROWED — что его взял участник, а MAINTENANCE запрещает выдачу. Дефис - обозначает отсутствие заёмщика. Закрытые поля можно менять только через методы. Прочитайте borrow: сейчас он присваивает BORROWED и нового участника без проверки прежнего состояния. Предскажите, что перезапишет повторная выдача. Конструктор, методы получения значений и enum уже готовы; сохраните их.
Каркас обработки команд тоже подготовлен:
cat Desk.java
Найдите вызов found.borrow(c[2]) и окружающий его try/catch. Цикл проверяет существование ID участника, но Tool должен защищать собственное состояние. IllegalArgumentException превращается в Rejected: ..., а цикл остаётся открытым. Проверка состояния должна происходить до обоих присваиваний: исключение после изменения оставило бы отклонённую выдачу частично применённой.
Перед редактированием сделайте резервную копию только исходного кода. mkdir -p создаёт папку при необходимости; cp копирует файл. Это ваши собственные резервные файлы, а не готовые ответы. Не копируйте и не сбрасывайте данные пункта выдачи и участников.
mkdir -p work
cp Tool.java work/Tool-before-borrow.java.txt
Откройте существующий файл в nano — текстовом редакторе терминала:
nano Tool.java
В nano символ ^ на панели сочетаний клавиш означает Ctrl. Удерживайте Ctrl, нажимая другую клавишу; не вводите сам знак. Нажмите Ctrl+W, введите state = State.BORROWED; и нажмите Enter, чтобы найти присваивание внутри borrow. Нажмите Ctrl+A, чтобы перейти к началу этой строки. Перемещайте курсор стрелками и исправляйте символы клавишей Backspace. Вставьте эту защитную проверку над присваиванием, сохранив два существующих присваивания и остальную часть класса:
if (state != State.AVAILABLE) {
throw new IllegalArgumentException("Tool is not available");
}
Здесь != означает «не равно». Условие отклоняет и существующую выдачу, и обслуживание; идентичность, название и примечание не меняются. Впишите ветвь в существующий метод, не заменяя класс целиком. Проверьте фигурные скобки и точку с запятой.
Нажмите Ctrl+O, чтобы сохранить, Enter, чтобы подтвердить существующее имя файла, затем Ctrl+X, чтобы выйти. Чтобы отказаться от несохранённой ошибочной правки, нажмите Ctrl+X и ответьте N на запрос сохранения. Снова откройте файл и попробуйте ещё раз. В оболочке nano Tool.java открывает его повторно; Ctrl+W находит тот же ориентир. При ошибке компиляции прочитайте имя файла и строку, исправьте это место в nano, сохраните и перекомпилируйте. Не запускайте программу после неудачной компиляции.
Если нужно отменить все правки исходного кода на этом шаге, следующая команда восстановления возвращает только вашу предыдущую копию Tool.java. Эти правки будут потеряны, поэтому используйте её лишь при намерении начать редактирование исходника заново; данные она никогда не сбрасывает. Это вариант восстановления, а не обычный следующий шаг:
cp work/Tool-before-borrow.java.txt Tool.java
После сохранения проверки (или повторного её добавления после восстановления) скомпилируйте и запустите программу:
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Введите эти команды пункта выдачи по порядку:
borrow A11 M01
list
borrow A11 M02
borrow A13 M01
borrow TYPO M01
borrow A12 M02
list
quit
Первая выдача принимается. Повторная выдача и выдача инструмента на обслуживании намеренно отклоняются с Rejected: Tool is not available. TYPO вызывает отказ из-за неизвестного ID; исправьте ID в следующей строке без сброса. A12 по-прежнему можно независимо выдать M02. Итоговый список должен сохранять A11 → M01, а также состояние обслуживания и примечание A13. quit возвращает в оболочку; desk.tsv остаётся неизменным. Метод возврата ещё не завершён — это работа следующего шага.
Разрешите возврат только записанному заёмщику
На этом шаге вы завершите обратный переход состояния, сохранив остальные выдачи.
Начните с приглашения оболочки на той же вкладке Terminal. Возврат допустим только из BORROWED и только если переданный участник совпадает с borrower. Для строк Java .equals() сравнивает содержимое, а ! отрицает результат сравнения. После обеих успешных проверок установите AVAILABLE и очистите заёмщика до -. Исключение до присваиваний не позволяет неудачному возврату частично изменить объект.
Сохраните проверку выдачи. Перед следующей правкой сделайте новую резервную копию только исходника, чтобы при восстановлении сохранился завершённый метод выдачи:
cp Tool.java work/Tool-before-return.java.txt
nano Tool.java
Нажмите Ctrl+W, найдите state = State.AVAILABLE; и нажмите Enter. Это первое присваивание внутри giveBack. Нажмите Ctrl+A, чтобы перейти к началу строки. Вставьте перед ней две проверки ниже; существующее присваивание состояния и borrower = "-"; оставьте после обеих проверок. Не заменяйте класс целиком и не удаляйте проверку выдачи.
if (state != State.BORROWED) {
throw new IllegalArgumentException("Tool is not borrowed");
}
if (!borrower.equals(member)) {
throw new IllegalArgumentException("Borrower does not match");
}
Первая ветвь отклоняет доступный инструмент и инструмент на обслуживании. Только выданный инструмент доходит до проверки личности. Сравнивайте участника с записанным заёмщиком, а не с отображаемым именем. Проверьте скобки, затем нажмите Ctrl+O, Enter, Ctrl+X, чтобы сохранить и выйти. Ctrl+X, N отменяет несохранённую ошибочную правку. Исправляйте ошибки компиляции, снова открыв файл и найдя нужный метод; до запуска добейтесь успешной компиляции. Чтобы намеренно отменить правки этого шага, сохранив проверку выдачи, выполните cp work/Tool-before-return.java.txt Tool.java, затем повторите только правку возврата. Не восстанавливайте более старую копию before-borrow.
Перекомпилируйте, чтобы программа использовала текущий исходник, затем откройте новый пункт выдачи в памяти. В этой работе каждый запуск начинает с исходного файла.
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv --memory
Введите эти команды пункта выдачи по порядку:
list
return A14 M01
return A13 M03
return A14 M03
borrow A14 M02
list
quit
Первый список показывает существующую выдачу A14 → M03. Неправильный заёмщик получает Rejected: Borrower does not match. Возврат инструмента на обслуживании даёт Rejected: Tool is not borrowed. Ни один отказ не изменяет объект. Правильный возврат даёт Accepted: A14 AVAILABLE -, после чего M02 может взять инструмент. A13 остаётся на обслуживании; A11 и A12 сохраняют отдельные ID и примечания.
Вы выразили два допустимых перехода: AVAILABLE → BORROWED и BORROWED → AVAILABLE. Из MAINTENANCE перехода возврата нет, и приложение не предоставляет команду управления обслуживанием. Отказ — нормальный результат операции; он не завершает цикл команд. Для практики можно запустить программу снова. В этой работе изменения намеренно исчезают после quit; сохраните исходный код и переходите к независимой работе о постоянном хранении, чтобы разобраться в причине.
Резюме
Вы использовали enum и закрытое состояние объекта для защиты выдачи инструментов. Одинаково названные инструменты сохранили разные ID, недопустимые действия не изменили объект, а допустимый возврат позволил выдать инструмент другому участнику. Следующая цель — сохранять результаты между запусками.



