TIL - JAVA spring DAY 4

회원관리 예제

오늘 회원관리라는 예제를 통해 벡엔드 개발을 해보면서 spring을 본격적으로 학습하는 첫걸음을 내딛게 되었다. 회원관리 서비스를 구현하기 위해서는

  • 비즈니스 요구사항 정리
  • 회원 도메인과 리포지토리 만들기 (오늘 할 내용)
  • 회원 리포지토리 테스트 케이스 작성
  • 회원 서비스 개발
  • 회원 서비스 테스트

다음과 같은 스테이지를 거쳐야했다. 먼저 비즈니스 요구사항이라함은 실제로 어떤 DB들이 입력되고 산출될것인가에 대한 선정 이슈와 어떠한 기능을 제공할것인지에 대한 선정 이슈였다. 본 예제는 간단한 서비스를 구현하는것이 목적이므로 회원ID이름 데이터로 구현이 가능하게끔 만들었다. 기능 또한 단순하게 회원을 등록하고 조회하는 식으로 동작 가능하도록 하였다. 또한 아직 데이터 저장소가 선정되지 않았음을 가정했다.

  • 데이터: 회원ID, 이름
  • 기능: 회원등록, 조회
  • 아직 데이터 저장소가 선정되지 않음 (가상의 시나리오)

구현에 앞서 일반적인 웹 애플리케이션이 어떠한 계층 구조를 가지고 동작하는지를 학습하였다.

  • 컨트롤러: 웹 MVC의 컨트롤러 역할
  • 서비스: 핵심 비즈니스 로직 구현
  • 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
  • 도메인: 비즈니스 도메인 객체. 예) 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장하고 관리됨

이를 통해 개발자는 이제 단순히 코딩만 하는것이 아니라 여러 도메인과 리포지토리의 관계, 서비스 측면에서 컨트롤러에 추가되어야할 기능 등등을 고려해야함을 알게 되었고, 이러한 스킬들을 가지고 능숙하게 해낼 수 있어야 좋은 프로그래머가 되지않을까란 생각을 해보았다.

각설하고

domain & repository

오늘 배운내용은 회원도메인과 리포지토리를 만드는 것이었다. 먼저 hello.hellospring package에 domain package를 생성하고 Member class를 생성한다.

그 후, Member class에 다음과 같이 비즈니스 요구사항에 따라 멤버변수를 정의한다.

package hello.hellospring.domain;

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;
    }
}

이 후, repository(저장소) package를 생성하고 다른 class에서도 가져다 쓸 수 있게끔 MemberRepository interface를 생성한다.

MemberRepository interface에 들어갈 내용은 다음과 같다.

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

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

public interface MemberRepository {
    Member save(Member member);
    Optional<Member> findById(Long Id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

MemberRepository interface의 멤버변수들을 설명하자면,

  • Member save(Member member); -> 회원을 저장하는 용도
  • Optional <Member> findById(Long Id); -> ID로 회원을 찾는 용도
    (Optional은 이번에 처음 알게된 클래스였는데, 자바 8에서 최초로 도입되었고, null값을 처리하기 위해서 만들어졌다고 한다.)
  • Optional<Member> findByName(String name);-> 이름으로 회원을 찾는 용도
  • List<Member> findAll(); -> 리스트에 해당하는 모든 회원을 찾음

interface를 만들었으니, 실제로 구현체를 만들어보겠다. 먼저, repository package 안에 MemoryMemberRepository class를 생성한다.

그 후, class 파일 안에 들어갈 내용이다.

package hello.hellospring.repository;

import hello.hellospring.domain.Member;

import java.util.*;

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에 넣기전에 member에 Id값을 할당
  				// (이름은 이미 회원가입할때 입력받으므로 don't care)
        store.put(member.getId(), member); //store에 저장 (Map에 저장됨)
        return member; 
  			
    }

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id)); // store.get(id). 즉,store에서 꺼내면됨
  				// but, null이 반환될 가능성이 있기 때문에 Optional로 감싼다.
    }

    @Override
    public Optional<Member> findByName(String name) {
       return  store.values().stream() // loop를 돌게함
               .filter(member -> member.getName().equals(name)) // 람다 사용 
  							// (member.getName이 parameter로 넘어온 name과 같은지 체크)
               .findAny(); // loop를 돌면서 Map에서 찾아지면 반환 
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values()); // store의 멤버들을 반환해줌
    }
}

주석들을 참고.

마무리하며....
이로써 모든 구현이 끝나고, Test case를 작성하는것은 다음 목표이다.
강의를 들으면서 학부때 공부했던 자바 백그라운드 지식들이 많이 등장했는데, 개념을 다시금 잡아야겠다는 생각이 들었다. HashMap이나 get, put과 같은 내용이 생소했다. 특히, Optional이라는 클래스는 이번기회에 새롭게 알게되었고 잘 숙지해야겠다.

좋은 웹페이지 즐겨찾기