본문 바로가기
spring

3. 서비스 개발

by Thumper 2021. 3. 26.

2편에 이어서 memberRepository와 domain을 활용해서 실제 비지니스 로직을 작성해보겠습니다.

 

Q.비지니스 로직(1편에서 세운 비지니스 요구사항)

 

 

1. src>main>java>hello.hellospring>service(패키지)>MemberService를 생성합니다. 

 

1. 전체코드

 

package hello.hellospring.Service;

import hello.hellospring.domain.Member;
import hello.hellospring.repositoty.MemberRepository;
import hello.hellospring.repositoty.MemoryMemberRepository;

import java.util.List;
import java.util.Optional;

public class MemberService {
    private final MemberRepository memberRepository = new MemoryMemberRepository();


    /*
    회원가입
     */
     //비지니스 조건: 중복회원X(:같은 이름의 회원가입은 허용X)
    public Long join(Member member) {
        
        validateDuplicateMember(member);
        memberRepository.save(member);
        return member.getId();

    }
 
    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
            .ifPresent(member1 -> {
            throw  new IllegalStateException("이미 존재하는 회원입니다.");
        });
    }

    /*
    전체회원조회
    */
    public List<Member> findMembers() {
        return memberRepository.findAll();
    }

    public Optional<Member> findOne(Long memberId) {
        return memberRepository.findById(memberId);
    }
}


 

Q1. MemberRepository를 만들기

 private final MemberRepository memberRepository = new MemoryMemberRepository();

회원서비스 개발에 필요한 회원리포지토리를 만들어줍니다.

 

 

 

Q2. 회원가입

/*
    회원가입
     */
    public Long join(Member member) {
        //비지니스 조건:(같은 이름의 중복된 회원가입X)
        validateDuplicateMember(member);
        memberRepository.save(member);
        return member.getId();

    }
    
    //중복회원 검증 도중에 에러발생 -> 판단: "같은 이름인데?" -> 알림: "이미 존재하는 회원이다"
    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
            .ifPresent(member1 -> {
            throw  new IllegalStateException("이미 존재하는 회원입니다.");
        });
    }

 

 


Q2 과정>

1단계

/*
    회원가입
     */
    public Long join(Member member) {
    
      Optional<Member> result = memberRepository.findByName(member.getName());
        result.ifPresent(member1 -> {
            throw  new IllegalStateException("이미 존재하는 회원입니다.");
        });
    
        memberRepository.save(member);
        return member.getId();
 }
  • 단순히 save를 호출해주고 ID만 반환해줍니다.
  • 회원가입할 때 "중복 이름 존재X"의 조건을 만들기 위해 member.Repository.findByName()으로 찾아본다.
  • Optional<Member>로 반환해서 result를 ifPresent()를 통해 중복된 회원가입을 찾아냅니다.

 

Q. Optional<>반환 -> result.ifPresent 조건식

Optional<Member>

java.util.Optional<T> 클래스

: Optional<T> 클래스는 Integer나 Double 클래스처럼 'T'타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)입니다.

따라서 Optional 인스턴스는 모든 타입의 참조 변수를 저장할 수 있습니다.

 

     ▶장점

        예상치 못한 NullPointerException 예외를 제공되는 메소드(예: ifPresent)로 간단히 회피할 수 있습니다.

        즉, 복잡한 조건문 없이도 널(null) 값으로 인해 발생하는 예외를 처리할 수 있게 됩니다.

 

     ▶result.ifPresent 조건식

        값이 있으면 조건로직을 동작하게 합니다 

        중복회원가입 경우 -> "이미 존재하는 회원입니다." 알림을 보냅니다.

 

 

2단계 : optional<> 지우기

어차피 result가 반환되기 때문에 optional을 지우고 바로 ifPresent()문을 해도 됩니다.

public Long join(Member member) {
        //비지니스 조건: 같은 이름의 회원 x : (중복회원x)
        memberRepository.findByName(member.getName())
            .ifPresent(member1 -> {
            throw  new IllegalStateException("이미 존재하는 회원입니다.");
        });
        memberRepository.save(member);
        return member.getId();
}

 

 

3단계 : extract Method(:단축키는 ctl+Alt+M)

지금처럼, findByName()해서 쭉 로직이 나오는 경우에는 method로 뽑는게 좋습니다.
순서: 마우스 오른쪽>refactor> Extract Method

이렇게 하면 깔끔하게 전체코드처럼 똑같이 코드가 정리됩니다.

 

 

 

 

 

 

2. Repository  vs   Service

MemberRepository는

  • 'save()' 'findById()' 'findByName()' 'findAll()'처럼 단순히 저장소에 넣었다 뺏다 느낌이 있었다.
  • 개발을 위한 단순한 이름짓기

MemberServiceService는

  • 'join()' 'validateDuplicateMembe()'로 좀 더 비지니스적인 느낌이 있었다.
  • 서비스와 매칭되는 부분으로 비지니스적인 용어로 이름짓기

 

마무리

이제 회원가입 도중 '중복회원가입'의 경우에 Exception(예외)가 잘 터지는지 검증해야 합니다.

저번 시간에 배운 '테스트케이스'를 통해 검증할 수 있는 '회원서비스를 테스트'를 배웁니다. 

 

 

※참고자료

optional<>자료  www.tcpschool.com/java/java_stream_optional

강의자료 www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard

댓글