728x90
목차
- 비즈니스 요구사항 정리
- 회원 도메인과 리포지토리 만들기
- 회원 리포지토리 테스트 케이스 작성
- 회원 서비스 개발
- 회원 서비스 테스트
이번 장에서는 회원 관리를 직접 해보는 예제를 다뤄볼 것입니다. 이는 백엔드 개발에 해당됩니다.
비즈니스 요구사항 정리
- 데이터 : 회원 ID, 이름 (굉장히 간단하게만 해볼겁니다.)
- 기능 : 회원 등록, 조회
- 아직 데이터 저장소가 선정되지 않음. (가상의 시나리오)
그림은 웹 어플리케이션의 계층구조입니다.
- 컨트롤러 : 웹 MVC의 컨트롤러 역할
- 서비스 : 핵심 비즈니스 로직 구현 (회원 ID는 중복이 안된다 같은 로직 등등)
- 리포지토리 : DB에 접근, 도메인 객체를 DB에 저장하고 관리.
- 도메인 : 비즈니스 도메인 객체, 예) 회원, 주문, 쿠폰 등등 주로 DB에 저장되고 관리됨.
- 아직 데이터 저장소가 선정되지 않아서, 우선 interface로 구현 클래스를 변경할 수 있도록 설계합니다.
- 데이터 저장소는 RDB, NoSQL 등등 다양한 저장소를 고민중인 상황으로 가정합니다.
- 개발을 진행하기 위해서 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소를 사용합니다.
회원 도메인과 리포지토리 만들기
- 우선 패키지로 domain, repository를 만들어줍니다.
- domain 안에 Member 클래스.
- repository 안에 MemberRepository 인터페이스와 MemoryMemberRepository 클래스를 만들어줍니다.
// Member 클래스
public class Member {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//MemberRepository 인터페이스
public interface MemberRepository {
Member save(Member member); //회원 저장
Optional<Member> findById(Long id);
Optional<Member> findByName(String name);
List<Member> findAll();
}
// MemoryMemberRepository 클래스
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
@Override
public Member save(Member member) {
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id));
}
@Override
public Optional<Member> findByName(String name) {
return store.values().stream()
.filter(member -> member.getName().equals(name))
.findAny();
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
}
우선 이렇게 만들어줍니다.
테스트를 해보고 싶습니다. 테스트를 해봅시다.
회원 리포지토리 테스트 케이스 작성
- 실무에선 테스트 케이스를 작성하는 것이 너무나도 당연한 것입니다.
- 개발한 기능을 실행해서 테스트 할 때 자바의 main메소드를 실행하거나, 웹 어플리케이션 컨트롤러를 통해 해당 기능을 실행합니다. 이러한 방법은 오래 걸린다는 단점이 있고, 반복해서 할 때 비효율적입니다.
- 그래서 자바는 JUnit이라는 프레임워크로 테스트를 실행해서 이런 단점을 극복합니다.
- 위의 코드가 실제로 동작하는지 테스트 케이스를 작성해봅시다.
- Main 패키지 밑에 test 패키지로 이동해서 똑같은 패키지들을 작성해줍니다.
- 그리고 보통은 테스트할거Test 클래스로 만들어줍니다.
public class MemoryMemberRepositoryTest {
MemberRepository repository = new MemoryMemberRepository();
@Test
public void save(){
Member member = new Member();
member.setName("Hello");
repository.save(member);
Member result = repository.findById(member.getId()).get();
Assertions.assertThat(member).isEqualTo(result);
}
@Test
public void findByName(){
Member member1 = new Member();
member1.setName("nonono");
repository.save(member1);
Member member2 = new Member();
member2.setName("hihihih");
repository.save(member2);
Member result = repository.findByName("nonono").get();
Assertions.assertThat(result).isEqualTo(member1);
}
@Test
public void findAll(){
Member member1 = new Member();
member1.setName("no");
repository.save(member1);
Member member2 = new Member();
member2.setName("yes");
repository.save(member2);
}
}
회원 서비스 개발
- service 패키지를 생성 후, MemberService 클래스를 구현해줍니다.
public class MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
//회원가입
public Long join(Member member){
//중복 회원 불가
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
memberRepository.save(member);
return member.getId();
}
// 전체 회원 조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
}
728x90
'Computer Science > SpringBoot' 카테고리의 다른 글
[SpringBoot] Spring Boot가 뭔데? 왜 쓰는데? (0) | 2022.01.29 |
---|---|
[SpringBoot] SpringBoot 웹 개발 기초 (0) | 2021.11.04 |
[SpringBoot] view 환경설정 (0) | 2021.11.02 |
[SpringBoot] 라이브러리 살펴보기 (0) | 2021.11.02 |
[SpringBoot] SpringBoot 시작하기 (start.spring.io) (0) | 2021.11.01 |
댓글