안녕하세요 jju_developer입니다.😄
지난 시간에 이어서 진행을 하도록 하겠습니다.
[스프링부트] 개발 전 테스트 요구사항 정리 01
안녕하세요 jju_developer입니다. 혼자 개인 프로젝트를 하다가 스프링부트에 대해서 더 공부할 필요성을 느껴서 하나씩 정리하면서 기록을 해보고자 합니다. 비즈니스 요구사항 정리 가장 쉬운거
jju240.tistory.com
지난 시간에 이어서 회원 도메인과 리포지토리를 코딩을 하면서 만들어 보도록 하겠습니다.
<목차>
1. 도메인 패키지에 Member class 생성
2. repository 패키지에 MemberRepository interface 생성
3. repository 패키지에 MemoryMemberRepository implements class 생성
1. 도메인 패키지에 Member class 생성
먼저 회원은 패키지를 도메인이라고 생성을 하겠습니다.
그리고 여기에 Member에 클래스를 만들겠습니다.
앞서 말씀드린 요구사항에서 Member 에는 ID, NAME이 있습니다.
아이디와 네임을 private으로 만든 후 getter, setter를 만들어 줍니다.
package org.project.whipping.domain;
public class Member {
//데이터를 저장하기 위한 id입니다. 고객이 지정한 아이디 아님
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
그리고 나서 repository를 만들 것입니다.
2. repository 패키지에 MemberRepository interface 생성
앞에서 만든 이 회원을 저장하는 저장소를 만드는 것입니다.
인터페이스로 생성합니다.
요 MemberRepository에 이제 지난 시간에 말씀드린 간단한 기능 두 가지를
인터페이스로 설계하도록 하겠습니다.
package org.project.whipping.repository;
import org.project.whipping.domain.Member;
import java.util.List;
import java.util.Optional;
public interface MemberRepository {
//1. 회원을 저장하는 기능
Member save(Member member);
//2. 위에 세이브한 회원을 찾는 기능
Optional<Member> findByID(Long id);
Optional<Member> findByName(String name);
List<Member> findAll();
}
여기서 잠깐!!! Optional 이란?
개발을 할 때 가장 많이 발생하는 예외 중 하나가 바로 NPE(NullPointerException)입니다.
이러한 NPE를 피하려면 null 여부를 검사해야 하는데, null 검사를 해야 하는 변수가 많은 경우
코드가 복잡해지고 번거롭습니다.그래서 요즘에는 Optional을 사용하여 감싸줍니다.
Java8에서는 Optional<T> 클래스를 사용하여 널포인트 익셉션을 방지할 수 있도록 도와주는 역할을 합니다.
Optional<T>는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로,
참조하더라도 NPE가 발생하지 않도록 도와주는 기능을 합니다.
(Optional은 null 또는 값을 감싸서 NPE(NullPointerException)로부터
부담을 줄이기 위해 등장한 Wrapper 클래스이지만Optional은 값을 Wrapping 하고 다시 풀고, null 일 경우에는 대체하는 함수를 호출하는 등의 오버헤드가 있으므로
잘못 사용하면 시스템 성능이 저하로 이어지기 때문에 메서드의 반환 값이 절대 null이 아니라면 Optional을 사용하지 않는 것이 좋습니다.즉, Optional은 메소드의 결과가 null이 될 수 있으며, null에 의해 오류가 발생할 가능성이 매우 높을 때 반환값으로만 사용되어야 하는 점 참고로 알아두시면 좋습니다!!ㅎ)
아무튼 다시 돌아와서
save를 하면 멤버를 저장하고, findAll의 기능은 모든 회원을 찾아주는 역할을 합니다.
3. repository 패키지에 MemoryMemberRepository implements class 생성
이제 구현체를 만들어 보도록 하겠습니다.
MemoryMemberRepository라는 클래스를 만들고 implements를 하겠습니다.
저장소에 저장을 하는 공간을 맵이라는 공간을 store라는 이름으로 생성해 줍니다~!
메모리에서 저장을 하려면 맵이 있어야겠죠?
코드 설명은 아래에 상세히 적어놓겠습니다.
package org.project.whipping.repository;
import org.project.whipping.domain.Member;
import java.util.*;
public class MemoryMemberRepository implements MemberRepository{
//memory 저장을 위해서 맵 사용 키는 회원아이디니까 long, 값은 Member로 합니다.
private static Map<Long, Member> store = new HashMap<>();
private static long sequence =0L;
//시퀀스는 0,1,2 키값을 자동으로 만들어 주는 아이입니다!
@Override
public Member save(Member member) {
//회원을 저장할때 할 일!
//회원을 저장할때 시퀀스 값을 하나씩 올려주고
member.setId(++sequence);
//스토어에 put으로 저장을 하고 멤버를 리턴해줄것입니다.
store.put(member.getId(),member);
return member;
}
@Override
public Optional<Member> findByID(Long id) {
//아이디를 찾을때에는 어떻게 하느냐!!
//그냥 스토어에 저장된 아이디를 겟하면 됩니다~
return Optional.ofNullable(store.get(id));
//return store.get(id);여기의 결과가 없으면 null이 될 가능성이 있기 때문에
//optional로 감싸서 반환을 해주는 것이다.
}
@Override
public Optional<Member> findByName(String name) {
//이름을 찾을때에는 자바의 람다식을 사용하여
//filter가 계속 돌면서 멤버가 찾고자 하는 이름이랑 같다면 finaAny로 반환하기
return store.values().stream()
.filter(member -> member.getName().equals(name))
.findAny();
//결과가 옵셔널의 null로 포함되어 아무것도 없으면 안함
}
@Override
public List<Member> findAll() {
//store는 맵인데 얘는 리스트 형태로 나옴
return new ArrayList<>(store.values());
//스토어에 있는 벨류가 맴버인데 맴버가 쭉 반환하도록 리스트로 만듦
}
}
이렇게 하면 기능 구현하고자 했던 회원 저장이랑 아이디 찾기랑 이름 찾기 등이 완성이 되었습니다.
다음시간에는 방금 만든 코드들이 잘 작동을 하는지!
테스트를 해보면서 잘 코딩이 되었는지 확인을 해보겠습니다.
여기까지 고생하셨습니다 ㅎㅎ!!
'☞Project > 휘핑크림' 카테고리의 다른 글
[스프링부트] 개발 전 회원 서비스 테스트 05 (0) | 2023.03.23 |
---|---|
[스프링부트] 개발 전 테스트 회원 서비스 개발 작성04 (0) | 2023.03.23 |
[스프링부트] 개발 전 회원 리포지토리 테스트 케이스 작성03 (0) | 2023.03.23 |
[스프링부트] 개발 전 테스트 요구사항 정리 01 (0) | 2023.03.23 |
[개인 프로젝트 01일차] 스프링 부트 초기 설정 개발환경 만들기!!+마이바티스+인텔리제이 (0) | 2023.03.21 |