동석쿠
프로그래밍 공부
동석쿠
전체 방문자
오늘
어제
  • 공부 (80)
    • 공부기록 (64)
      • 웹개발 (6)
      • Java (7)
      • cs 공부 (3)
      • http 웹 기본 지식 (8)
      • 자바 스프링 (20)
      • 개인 미니프로젝트 (3)
      • 알고리즘 공부 (6)
      • 면접준비 (2)
      • 프론트공부 (8)
      • 파이썬 플라스크 (1)
    • 항해99 기록 (14)
      • 회고록 (10)
      • 팀프로젝트 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • JPA
  • 파이썬
  • lombok
  • 리프레쉬토큰
  • 리스트
  • 자바
  • 스프링부트
  • API
  • 알고리즘
  • 상속
  • 항해99
  • 리액트
  • 프로그래머스
  • 리프레시토큰
  • Java
  • 스프링
  • Post
  • Get
  • 자바스크립트
  • 문법

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
동석쿠
공부기록/자바 스프링

스프링 아이템기능 리팩터링

공부기록/자바 스프링

스프링 아이템기능 리팩터링

2022. 3. 19. 17:19

https://dongseokstudy2.tistory.com/121?category=916641 

 

스프링 아이템기능 구현, 단어 뒤집기, 파파고 API

프로젝트 기능중 채팅방에서 유저가 아이템을 쓸 수 있는 기능이 있다. 유저가 아이템을 사용하기 위해선 아이템을 구매할 수 있어야 한다. @GetMapping("/mypage/{item}") @ApiOperation(value = "아이템 구매"

dongseokstudy2.tistory.com

전에 만들었던 아이템관련 코드들은 위에 정리되어있다.

기존 코드의경우 코드가 너무 길고 switch문과 if문이 많이 들어가있기도해서 이점을 고쳐보려한다.

 

case "onlyMe":
                buyitem.setOnlyMe(buyitem.getOnlyMe() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, onlyMePrice, "나만 말하기");
                break;
 private void itemBuy(User user, Long price, String item) {
        if (user.getTotalPoint() >= price) {
            user.setTotalPoint(user.getTotalPoint()-price);
            userRepository.save(user);
            Point point = new Point(item + " 구매", -price, user.getTotalPoint(), user);
            pointRepository.save(point);
        } else {
            throw new LackPointException("보유한 포인트가 부족합니다");
        }
    }

기존 코드 switch문에 한문단과 그안에있는 itemBuy메소드를 가져왔다. 

itemBuy는 유저엔티티와 가격 그리고 아이템 이름을 받아와 유저의 포인트에 아이템의 가격만큼 뺴주고

포인트 내역을 만들때는 아이템이름과 가격을 사용해서 내역을 만든다.

 

기존 테이블구조는 유저 - 아이템이 OneToOne관계로 아이템 테이블에는 Integer형 변수명으로 아이템의 이름이 있고 해당하는 아이템의 갯수가 있다. 

 

우선 코드를 줄이기 위해 아이템의 가격과 이름을 enum값으로 바꾸기로 했다.

@NoArgsConstructor
@Getter
public enum ItemType {
        bigFont("bigFont", 100L, "내 글자 크게 만들기"),
        onlyMe("onlyMe", 100L, "나만 말하기"),
        myName("myName", 100L, "모두 내이름으로 바꾸기"),
        papago("papago", 100L, "나만빼고 랜덤으로 번역하기"),
        reverse("reverse", 100L, "나만빼고 반대로 말하기"),
        exBuy("exBuy", 100L, "경험치 구매");
        private String itemCode;
        private Long price;
        private String itemName;

        ItemType(String itemCode, Long price, String itemName) {
            this.itemCode = itemCode;
            this.price = price;
            this.itemName = itemName;
    }
}

각각 타입에는 itemCode(프론트와 주고받을 이름), price(아이템 가격), itemName(아이템의 이름) 이 담겨있다.

이제 아이템의 테이블 구조를 바꿔줄 차례다

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@Table(name = "item")
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column
    private String itemCode;

    @Column
    private Long cnt;

    @ManyToOne
    @JoinColumn(name = "userId")
    private User user;

    public void setCnt(Long cnt) {
        this.cnt = cnt;
    }

    public Item(String itemCode, Long cnt, User user) {
        this.itemCode = itemCode;
        this.cnt = cnt;
        this.user = user;
    }

기존 단순히 private Integer ItemName; 이렇게 있는것에서 아이템의 코드와 갯수 그리고 주인인 유가 들어가게 설계했다.

이렇게 바꾸고 난후 유저와 아이템을 OneToMany로 일대다관계를 맺어준다. 

 

@Transactional
    public void buyItem(ItemType item, User user) {

        if (user.getTotalPoint() < item.getPrice()) {
            throw new LackPointException("보유한 포인트가 부족합니다");
        }
        user.setTotalPoint(user.getTotalPoint() - item.getPrice());
        userRepository.save(user);

        if (item.getItemCode().equals("exBuy")) {
            user.setEx((int) (user.getEx() + item.getPrice()));
            userRepository.save(user);
        } else {
            Item userItem = itemRepository.findByUser_IdAndItemCode(user.getId(), item.getItemCode());
            userItem.setCnt(userItem.getCnt() + 1);
            itemRepository.save(userItem);
        }

        Point point = new Point(item.getItemName() + "구매", -item.getPrice(), user.getTotalPoint(), user);
        pointRepository.save(point);

    }

아이템 구매의 서비스 로직이다.

위에서 유저의 포인트가 아이템 가격보다 싼지 확인하고 유저의 포인트롤 아이템의 가격만큼 차감하고

exBuy의 경우는 경험치 구매이기때문에 다른 방식으로 save를 하고 나머지 아이템들의 경우 그 아이템의 갯수만 조절해주면된다. 이렇게 할경우 코드가 훨씬 짧아진다.

 

 //아이템 사용
    @Transactional
    public void useItem(ItemType item, User user) {
        Item userItem = itemRepository.findByUser_IdAndItemCode(user.getId(), item.getItemCode());

        if (userItem.getCnt() > 0) {
            userItem.setCnt(userItem.getCnt() - 1);
            itemRepository.save(userItem);
        } else {
            throw new ItemNotFoundException("아이템이 없습니다");
        }
    }

아이템 사용 로직의 경우도 기존 코드에비해 훨씬 짧아진것을 확인할 수 있다.

 

기존의 단순 if elseif를 반복하여 각각 if문에서 아이템구매를 해주는 방식은 애초에 의존성주입도 안되있어 아이템의 가격이 바뀌거나 무언가 추가될경우 서비스코드에 무언가를 수정해주어야하는데 리팩터링된 코드는 enum의 값을 수정해주면 OK다.

'공부기록 > 자바 스프링' 카테고리의 다른 글

Querydsl 공부 <환경 설정 및 기본 엔티티 설정>  (0) 2022.05.26
JPA 연관관계  (0) 2022.04.17
스프링 아이템기능 구현, 단어 뒤집기, 파파고 API  (0) 2022.03.12
스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정  (0) 2022.03.09
스프링 배팅시스템 만들기 (트위치 배팅시스템 참고)  (0) 2022.03.08
    '공부기록/자바 스프링' 카테고리의 다른 글
    • Querydsl 공부 <환경 설정 및 기본 엔티티 설정>
    • JPA 연관관계
    • 스프링 아이템기능 구현, 단어 뒤집기, 파파고 API
    • 스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정
    동석쿠
    동석쿠
    프로그래밍 공부동석쿠 님의 블로그입니다.

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.