Giken Dev
article thumbnail
반응형

https://github.com/prgrms-be-devcourse/java-library-management/pull/34

 

[5기 - 박주한] 1~2주차 과제: 도서 관리 어플리케이션 제출합니다. by ParkJuhan94 · Pull Request #34 · prg

안녕하세요 도찌, 무송 멘토님! 이번 과제를 하면서 많은걸 배운것 같아요. 출력과 예제를 통해서 어느정도 test 하면서 진행을 했는데, 계속된 버그에 테스트코드가 꼭 필요한 것 같긴 했습니다.

github.com

 

 

 

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 의 장점

 

기본 Enum Type : 코드에 마우스를 위치할 때 String 만 존재

 

코드 작성할 때 의미를 알기가 힘듦
코드 작성할 때 연관된 문자를 보여줌!

 

 

 

 

 

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;
    }
}

 

자바의 스케줄링 기능을 활용합니다.

이를 통해 특정 작업을 미래에 실행하거나 주기적으로 반복 실행할 있습니다.

반응형
profile

Giken Dev

@기켄

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!