Framework/Spring Boot

회원 관리 예제 #01 비즈니스 요구사항 정리, 회원 도메인과 리포지토리 만들기

반응형

비즈니스 요구사항 정리

  • 데이터: 회원ID, 이름
  • 기능: 회원 등록, 조회
  • 아직 데이터 저장소가 선정되지 않음(가상의 시나리오)
    • 데이터 저장소가 선정되지 않아, 인터페이스로 구현 클래스를 변경할 수 있도록 설계
    • 데이터 저장소는 RDB, NoSQL등 다양한 저장소를 고민중인 상황으로 가정
    • 개발을 진행하기 위해 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소를 사용

일반적인 웹 애플리케이션 계층 구조

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

→ 도메인 개념을 간략하게나마 짚고 넘어간다. 

회원 도메인과 리포지토리 만들기

회원 도메인

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

여기서 회원 도메인이란 Spring MVC Legacy 프로젝트에서 썼던 VO나 DTO와 같은 것을 의미하는 것 같다. 데이터베이스에 저장되는 객체를 자바 언어로 풀어놓고 getter와 setter를 generate해주었다.

멤버 리포지토리

멤버 리포지토리는 학원 프로젝트에서 배웠던 DAO와 같은 개념으로 보인다. 명칭만 다르고 역할은 동일한 듯. 인터페이스와 구현 클래스로 파일이 나눠진다. 

인터페이스
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();
}
 클래스
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.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(); //루프를 맵에서 돌면서 하나라도 찾아지면 바로 반환해버리고, 없으면 옵셔널에 null이 포함되어서 반환됨
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }
}

여기서 Optional이라는 부분은 자바8부터 적용된 부분이라는데, 반환값이 없을 경우 null을 반환해주는 객체라고 한다. 음.. 아직은 잘 모르겠지만 뒷부분에서 좀 더 다룬다고 하니까 잘 따라가보자.

아직까지는 스프링부트가 좀 어색하지만 현업에 가서도 소스가 있으면 충분히 분석할 수 있을 것 같다. 이상하게 코테스터디 깃허브 리포지토리에선 다른사람소스 읽는게 좀 힘든데 프로젝트 할 때에도 이클립스에서는 남의 소스 분석하는 일이 잦았다... 

728x90
반응형