들어가며

개발자에게 유명한 책으로 알려진 마틴 파울러의 저서 리팩토링 의 내용을 보면, 메서드를 분리할때 의도구현을 기준으로 삼으라고 말하고 있다.

의도와 구현

그럼 의도와 구현은 무슨 의미일까?

**의도**
코드가 어떠한 일을 하려는지 잘 표현하고 있다면 그 코드는 의도를 드러낸 코드이다.

**구현**
코드가 어떠한 일을 하는지  잘 이해가 되지 않는다면 그 코드는 구현을 드러낸 코드이다.
(시간을 들여서 이해를 해야되는 코드)

우리가 해야되는건

구현 코드를 메서드로 추출해서 메서드의 이름을 적절하게 지음으로써 의도를 드러내게 한다.

이때 주석이 사용되었다면 좋은 기준이 되는데, 주석이 사용된 부분을 메서드로 추출하고 주석을 메서드의 이름으로 채용하면 된다.

실제로 적용해보기

이번에 적용해볼 대상은 금나와라 뚝딱(이하 금뚝)에 있는 랜덤으로 선물을 선택하는 메서드이다.

직접 보도록하자.

리팩토링 전

public GiftItemSimpleDto chooseGiftItemByRandom(Long eventId, Long memberId) {
    Event event = eventRepository.findByIdForUpdate(eventId)
        .orElseThrow(() -> new EntityNotFoundException(Event.class, eventId));
    event.validateEventRunning();
    Member member = memberRepository.findByIdWithGroup(memberId)
        .orElseThrow(() -> new EntityNotFoundException(Member.class, memberId));
    checkAlreadyParticipatedMember(event, member);

    int candidateCount = event.getLeftGiftCount() + event.getLeftBlankCount();
    if (candidateCount <= 1) {
        event.closeEvent();
    }
    int offset = new Random().nextInt(candidateCount);
    Optional<GiftItemSimpleDto> maybeGiftItem = giftItemQueryRepository.findSimpleGiftItemByRandom(eventId,
        offset);
    if (maybeGiftItem.isPresent()) {
        GiftItemSimpleDto chosenGiftItem = maybeGiftItem.get();
        event.decreaseLeftGiftCount();
        giftItemRepository.allocateMemberToGiftItem(chosenGiftItem.getGiftItemId(), memberId);
        eventLogRepository.save(
            new EventLog(event, member, giftRepository.getById(chosenGiftItem.getGiftId()),
                giftItemRepository.getById(chosenGiftItem.getGiftItemId())));
        return chosenGiftItem;
    } else {
        event.decreaseLeftBlankCount();
        eventLogRepository.save(new EventLog(event, member, null, null));
        throw new GiftBlankDrawnException();
    }
}