https://github.com/prgrms-be-devcourse/java-library-management/pull/34
Java Enum 활용기
개발을 진행할때 Enum을 통해 얻는 기본적인 장점들은 아래와 같습니다.
- 문자열과 비교해, IDE의 적극적인 지원을 받을 수 있습니다.
- 허용 가능한 값들을 제한할 수 있습니다.
- 리팩토링시 변경 범위가 최소화 됩니다.
이 장점들은 모든 언어들의 Enum에서 얻을 수 있는 공통된 장점입니다.
하지만 Java의 Enum은 이보다 더 많은 장점을 갖고 있습니다.
C/C++의 경우 Enum이 결국 int값이지만, Java의 Enum은 완전한 기능을 갖춘 클래스이기 때문입니다.
(이 글의 제목이 Enum 활용기가 아닌, Java Enum 활용기인것도 이 때문입니다.)
by. https://techblog.woowahan.com/2527/
여러 클래스에서 사용할 것이라서 클래스 밖에 독립적으로 위치
기본적인 Enum Type
package com.libraryManagement.domain;
public enum ChangeBookStatus {
APPLYRENT,
APPLYRETURN,
APPLYLOST,
APPLYDELETE
}
[Java Enum기본메서드]
1. name() : 호출된 값의 이름을 String으로 리턴.
System.out.println(ChangeBookStatus.APPLYRENT.name());
2. values() : enum의 요소들을 순서대로 enum타입의 배열로 리턴.
(ENUM$VALUES)의 카피임으로 자주 호출하지 않길
for(ChangeBookStatus changeBookStatus : ChangeBookStatus.values()){
System.out.println(changeBookStatus);
}
3. valueOf() : 매개변수로 주어진 String과 열거형에서 일치하는 이름을 갖는 원소를 리턴
System.out.println(ChangeBookStatus.valueOf("APPLYLOST"));
연관시킬 문자를 가진 Enum Type
package com.libraryManagement.domain;
public enum BookStatus {
POSSIBLERENT("대여가능"),
NOPOSSIBLERENT("대여중"),
READY("준비중"),
LOST("분실됨"),
DELETE("삭제됨");
final private String name;
public String getName() {
return name;
}
BookStatus(String name) {
this.name = name;
}
}
- 도서상태를 나타내는 String
- 상수("연관시킬 문자")
- 연관시킬 문자를 필드로 가지고있어야 합니다.
- getter 필요
- 생성자 필요
System.out.println(BookStatus.NOPOSSIBLERENT.getName());
System.out.println(BookStatus.NOPOSSIBLERENT.name());
연관시킬 문자를 가진 Enum Type 의 장점
Builder 디자인패턴
package com.libraryManagement.domain;
public class Book {
private final long id;
private final String title;
private final String author;
private final int pages;
private String status;
public static class Builder {
private long id;
private String title;
private String author;
private int pages;
private String status;
public Builder id(long id) {
this.id = id;
return this;
}
public Builder title(String title) {
this.title = title;
return this;
}
public Builder author(String author) {
this.author = author;
return this;
}
public Builder pages(int pages) {
this.pages = pages;
return this;
}
public Builder status(String status) {
this.status = status;
return this;
}
public Book build() {
return new Book(this);
}
}
public Book(Builder builder) {
this.id = builder.id;
this.title = builder.title;
this.author = builder.author;
this.pages = builder.pages;
this.status = builder.status;
}
public long getId() {
return id;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public int getPages() {
return pages;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public String toString() {
return "도서번호 : " + id +
"\n제목 : " + title +
"\n작가 이름 : " + author +
"\n페이지 수 : " + pages + " 페이지" +
"\n상태 : " + status + "\n";
}
}
public Book createBook() throws IOException {
long id = bookService.getNumCreatedBooks() + 1;
DtoBook dtoBook = bookIO.inputBookInsert();
String title = dtoBook.getTitle();
String author = dtoBook.getAuthor();
int pages = dtoBook.getPages();
String status = POSSIBLERENT.getName(); // 대여가능 상태로 생성
return new Book
.Builder()
.id(id)
.title(title)
.author(author)
.pages(pages)
.status(status)
.build();
}
Builder pattern의 장점
- 가독성 향상
- Build 패턴은 객체 생성 및 설정 단계를 분리합니다. 이로 인해 코드의 가독성이 향상됩니다. 객체의 필드를 설정하는 메서드 호출이 연이어 이루어지므로 코드의 의도가 명확하게 드러납니다.
- 불변성 보장
- Build 패턴은 불변성 (immutability)을 보장할 수 있습니다. 객체를 생성한 후 변경할 수 없도록 만들어야 하는 경우, 빌더 패턴을 사용하여 객체를 생성하고 필요한 필드를 설정한 다음 변경할 수 없도록 빌더 객체를 "빌드"하여 원하는 불변 객체를 얻을 수 있습니다.
대여신청하면 정리중 상태로 바뀌고, 5분뒤에 자동으로 대여가능으로 바뀌도록
public class BookService {
private final Repository repository;
private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public String updateBookStatus(String applyType, long id) throws InterruptedException {
if(applyType.equals(APPLYRENT.name())){
if(isPossibleUpdateBookStatus(applyType, id)){ // 대여할 수 있다면
repository.updateBookStatus(id, NOPOSSIBLERENT.getName());
return POSSIBLERENT.getName();
}else{
return repository.findBookById(id).getStatus();
}
}else if(applyType.equals(APPLYRETURN.name())) {
if(isPossibleUpdateBookStatus(applyType, id)){ // 반납할 수 있다면
repository.updateBookStatus(id, READY.getName());
// 5분 후에 대여 가능 상태로 변경합니다.
scheduler.schedule(() -> {
repository.updateBookStatus(id, POSSIBLERENT.getName());
}, 5, TimeUnit.MINUTES);
}
}else if(applyType.equals(APPLYLOST.name())) {
if(isPossibleUpdateBookStatus(applyType, id)){ // 분실처리할 수 있다면
repository.updateBookStatus(id, LOST.getName());
}
}else if(applyType.equals(APPLYDELETE.name())) {
if(isPossibleUpdateBookStatus(applyType, id)){ // 삭제처리할 수 있다면
repository.updateBookStatus(id, DELETE.getName());
}
}
return null;
}
}
자바의 스케줄링 기능을 활용합니다.
이를 통해 특정 작업을 미래에 실행하거나 주기적으로 반복 실행할 수 있습니다.
'백엔드 데브코스' 카테고리의 다른 글
[Java] 어댑터패턴에 관한 예제 (0) | 2023.10.09 |
---|---|
[Java] 디자인패턴과 안티 패턴 (0) | 2023.10.08 |
[Java] SOLID란? (2) - 객체 지향 프로그래밍의 5가지 기본 원칙 (0) | 2023.09.29 |
[Java] SOLID란? (1) - 객체 지향 프로그래밍의 5가지 기본 원칙 (0) | 2023.09.27 |
[Java] 의존성을 주입해주는 주체 - jar, @Profile, @Order (0) | 2023.09.27 |