요구사항
- ⬜ 도서를 대여할 수 있어야 한다.
- ⬜ 대여 중인 도서는 다시 대여할 수 없다.
- ⬜ 반납 기능이 있어야 한다.
문제 풀이
Main
더보기
package lv_3;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Library library = new Library(new ArrayList<>());
library.addBook(new Book("The Little Prince", "Antoine de Saint-Exupéry", 1943));
library.addBook(new Book("Cinderella", "Charles Perrault", 1697));
while(true) {
showMenu();
int input = Integer.parseInt(scanner.nextLine());
switch (input) {
case 0 -> {
System.out.println("프로그램을 종료합니다.");
return;
}
case 1 -> library.rentBook(scanner.nextLine());
case 2 -> library.returnBook(scanner.nextLine());
case 3 -> library.printBook(scanner.nextLine());
case 4 -> library.printAllBook();
}
}
}
// 메뉴를 보여준다.
public static void showMenu() {
System.out.println("[ Library Menu ]");
System.out.println("0. 종료");
System.out.println("1. 도서 대여");
System.out.println("2. 도서 반납");
System.out.println("3. 도서 검색");
System.out.println("4. 도서 목록 출력");
}
}
- Scanner 객체를 생성하여, 사용자로부터 입력을 받을 수 있게 하였습니다.
- 반복적으로 보여지는 메뉴를 메서드화 하였습니다.
- 입력에 따른 행동을 수행하도록 switch 문을 통해 나타내었습니다.
Library
더보기
package lv_3;
import java.util.List;
import java.util.Optional;
public class Library {
private final List<Book> bookList;
public Library(List<Book> bookList) {
this.bookList = bookList;
}
public void addBook(Book book) {
bookList.add(book);
}
public Optional<Book> findBookByTitle(String title) {
for(Book book : bookList) {
if(book.getTitle().equalsIgnoreCase(title)) {
return Optional.of(book);
}
}
return Optional.empty();
}
public void printBook(String title) {
Optional<Book> book = findBookByTitle(title);
if (book.isPresent()) {
Book foundBook = book.get();
System.out.println(foundBook + "\n");
} else {
System.out.println(title + "은/는 존재하지 않는 책입니다.\n");
}
}
public void printAllBook() {
System.out.println("[ 전체 책 목록 ]");
for(Book book : bookList) {
System.out.println(book);
}
System.out.println();
}
public void rentBook(String title) {
Optional<Book> book = findBookByTitle(title);
if(book.isPresent()) {
Book foundBook = book.get();
if (foundBook.Rented()) {
System.out.println(foundBook.getTitle() + " : 이미 대여된 책입니다.\n");
} else {
System.out.println(foundBook.getTitle() + " : 대여 완료\n");
book.get().setRented(true);
}
} else {
System.out.println(title + "은/는 존재하지 않는 책입니다.\n");
}
}
public void returnBook(String title) {
Optional<Book> book = findBookByTitle(title);
if(book.isPresent()) {
Book foundBook = book.get();
if (foundBook.Rented()) {
System.out.println(book.get().getTitle() + " : 반납 완료\n");
book.get().setRented(false);
} else {
System.out.println(foundBook.getTitle() + " : 이미 반납된 책입니다.\n");
}
} else {
System.out.println(title + "은/는 존재하지 않는 책입니다.\n");
}
}
}
- 기존의 findAndPrintBookByTitle() 메서드를 findBookByTitle()과 printBook()으로 분리하였습니다.
- rentBook()와 returnBook() 메서드를 통해 책 대여 상태를 변경해주었습니다. Optional를 사용하여, null에 대해서도 안전하게 처리해주었습니다.
Book
더보기
package lv_3;
public class Book {
private String title;
private String author;
private int publishYear;
private boolean isRented;
public Book(String title, String author, int publishYear) {
this.title = title;
this.author = author;
this.publishYear = publishYear;
}
public void setRented(boolean rent) {
isRented = rent;
}
public boolean Rented() {
return isRented;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return String.format("제목 : %-20s | 저자 : %-30s | 출판 연도 : %-13s",title,author,publishYear);
}
}
객체의 역할과 책임
Main | Library | Book |
Scanner 객체 생성 | 책 추가 | 책의 정보 보관 |
Library 객체 생성 | 책 검색 | 자기 자신의 정보를 문자열로 표현 |
Book 객체 생성 | 책 대여 및 반납 로직 처리 | 책의 정보 제공 |
전체 흐름 처리 | 도서 출력 |
실행 흐름
GPT 분석
`Book` 클래스의 상태 변경 책임 강화
- 현재 상태 변경은 외부에서 setRent(true)로 처리되고 있어, 객체의 자율성이 떨어집니다. 행동 메서드로 상태 변경을 위임하는 것이 객체지향적으로 더 좋습니다
- 객체의 내부 상태를 외부에서 조작하게하면, 객체가 스스로 자신의 상태를 지키지 못하는 구조. 즉, 객체의 자율성이 떨어진다라고 표현합니다.
- 내부 구조가 외부에 노출되어 캡슐화가 깨진다.
- 변경을 하게 되면, 외부 코드를 다 고쳐야 한다.
중복 메시지 출력 개선
- rentBook() / returnBook() 등에서 System.out.println()을 여러 번 쓰기보다는, 메시지 생성을 메서드로 분리할 수 있어요.
또는 출력을 별도의 Printer 클래스에 위임하는 것도 SRP 측면에서 좋습니다 (Lv4에서 적용해볼 수 있음).
`Library` 클래스의 책임이 조금 과해짐
- 책 추가, 책 검색, 책 대여 및 반납 로직 처리, 도서 상태 출력
- 개선 제안 : 책의 상태는 Book이, 출력은 별도의 `Printer` 또는 `View` 객체가 담당하면 더 명확합니다.
'JAVA' 카테고리의 다른 글
[Java] Enum (0) | 2025.05.04 |
---|---|
[Java] Lv_4 도서관 프로젝트 (0) | 2025.05.02 |
[Java] Lv_2 도서관 프로젝트 (0) | 2025.05.01 |
[Java] Lv_1 도서관 프로젝트 (0) | 2025.05.01 |
[Java] 도전 과제 Lv_2 키오스크 (0) | 2025.04.28 |