인프런 스프링-7

Cloudman·2022년 11월 27일
0

항해99 스프링 공부

목록 보기
9/15

회원 관리 예제



진행 과정

  1. 비즈니스 요구사항 정리
  2. 회원 도메인과 리포지토리 만들기
  3. 회원 리포지토리 테스트 케이스 작성
  4. 회원 서비스 개발
  5. 회원 서비스 테스트


1) 비즈니스 요구사항

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

위의 구조가 일반적인 계층 구조이다.

  • 컨트롤러 : 웹 MVC 의 컨트롤의 역할 또는 API 를 만드는 역할
  • 서비스 : 비즈니스 도메인 객체를 가지고 핵심 비즈니스 로직이 동작하도록 구현한 계층
    예) 중복가입 방지 같은 로직들
  • 도메인 : 회원, 주문, 쿠폰 등 DB에 저장하고 관리되는 비즈니스 도메인 객체
  • 리포지토리 : DB 에 접근, 도메인 객체를 DB에 저장하고 관리

개발은 해야 하기 때문에 메모리 구현체로 만들 것이다.
메모리에서 넣었다 뺐다 할 수 있는 방식

  • 위에서 적어놨듯이 아직 데이터 저장소가 선정되지 않은 상태 이므로 우선, 인터페이스로 구현 클래스를 변경할 수 있도록 설계한다.
  • 데이터 저장소는 아직 고민중인 상황(RDB, NoSQL, MyBatis 등)
  • 개발 진행을 위해 초기 개발 단계에서는 구현체로 가변운 메모리 기반의 데이터 저장소 사용





2) 회원 도메인과 리포 만들기

우선 강의를 따라서 domain 패키지와 repository 패키지를 만들어 준다.

다음으로 Member 클래스를 만들어 준다.

위의 요구사항에 있던 두가지 id, name 필드와 Getter, Setter 생성




// 회원 정보를 저장하는 저장소 구현
public interface MemberRepository {
    // 기능 구현

    // 회원 정보 저장 기능
    Member save(Member member);

    // 회원 아이디를 찾는 기능
    Optional<Member> findById(Long id);

    // 회원 이름을 찾는 기능
    Optional<Member> findByName(String name);

    // 모든 회원의 정보를 찾는 기능
    List<Member> findAll();
}

주석으로 달아 놓았듯이 저장소 구현 및 안에 필요한 기능들을 구현하기 위해서 인터페이스를 만들어 준다.

// 구현체 만들기
public class MemoryMemberRepository implements MemberRepository {

    // 실무에서는 공유되는 변수에서 동시성 문제 때문에 컨커런스? 를 써야 하는데
    // 여기서는 단순한 예제이기 때문에 HashMap 을 사용
    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;

    @Override
    public Member save(Member member) {
        // 아이디는 자동으로 숫자가 1 씩 증가하면서 저장 즉, 자동 지정
        // 이후에 store 에다가 가져온 아이디를 store 라는 Map 에 저장
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    }

    @Override
    public Optional<Member> findById(Long id) {
        // null 이 반환될 가능성이 있으면 Optional.ofNullable 을 이용해서
        // null 을 감싸서 반환한다.
        return Optional.ofNullable(store.get(id));
    }

    @Override
    public Optional<Member> findByName(String name) {
        // 스트림을 사용해서 구현(자바 8의 람다 사용)
        // 루프를 돌린다. filter를 이용해서 member 에서
        // member.getName() 의 값과 파라미터로 넘어온 name( findByName(String name) ) 과
        // equals 를 통해 같은지 확인해준다. 찾으면 반환 없으면 Optional 에 의해 null 을 반환
        // findAny(); 는 하나라도 찾는 기능을 말한다고 한다...(이게 뭔소리야;;)
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

    @Override
    public List<Member> findAll() {
        // 위에서 보면 member 는 map 이지만 여기서는 List 형태 이다.
        // store.values() : store 에 있는 values() 는 member 를 의미한다.
        // 즉, member 를 반환 한다는 의미이다.
        return new ArrayList<>(store.values());
    }
}

이번에는 구현체를 만들어 준다.

위에서 보면 내가 아직 모르는 기능이나 함수들이 많은데.. 이는 아직 자바 공부 부족이므로 그냥 차차 알아가야 할 것 같다.

profile
코린이

0개의 댓글