객체에 대여 규칙 넣기

JavaBeginner
지금 연습하기

소개

지역 공구 대여 창구는 등록 회원에게 실제 공구를 빌려줍니다. 드릴 두 개의 이름이 같아도 서로 다른 대여 관계에 속할 수 있습니다. 정비 중인 공구는 계속 대여 불가 상태여야 하며, 대여 중인 공구는 기록된 회원만 반납할 수 있어야 합니다.

이 규칙을 Java 객체에 넣은 다음 준비된 작은 명령 루프를 사용합니다. 첫 번째 실습에서는 변경 내용을 메모리에만 유지하고, 다음 실습에서 저장을 배웁니다. Java 클래스, 메서드, private 필드, 리스트, 기본 예외를 알고 있어야 합니다. 읽기와 연습 시간은 작성자 추정으로 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는 대여가 차단됨을 뜻합니다. 하이픈 -는 대여 회원이 없다는 뜻입니다. private 필드는 메서드를 통해서만 바뀔 수 있습니다. borrow를 읽으세요. 현재는 이전 상태를 확인하지 않고 BORROWED와 새 회원을 대입합니다. 두 번째 대여가 무엇을 덮어쓸지 예상해 보세요. 생성자, getter와 열거형은 이미 완성되어 있으므로 그대로 두세요.

명령 처리 틀도 준비되어 있습니다.

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 뒤에 변경 내용이 사라지는 것은 의도된 동작입니다. 소스는 보관하고, 독립적인 영속성 실습으로 넘어가 그 이유를 배우세요.

요약

열거형과 객체의 private 상태로 공구 대여를 보호했습니다. 이름이 같은 공구도 서로 다른 ID를 유지했고, 잘못된 동작은 객체를 바꾸지 않았으며, 유효한 반납 뒤에는 다른 회원이 다시 빌릴 수 있게 됐습니다. 다음 학습 목표는 실행 사이에 결과를 저장하는 것입니다.