본문 바로가기

프로그래밍/- Spring

[ 스프링 핵심 원리 이해1 ] 예제 만들기(순수 Java) : 프로젝트 생성~회원도메인 실행과 테스트

 

프로젝트 생성

 

 

➡️https://start.spring.io/ >> 프로젝트 생성 도구

 

 

 

 

 

비즈니스 요구사항과 설계

 

 

➡️ 회원

  🔸회원 가입, 조회

  🔸일반과 VIP 두가지 등급

  🔸회원 데이터는 자체 DB 구축, 외부 시스템과 연동 두 가지의 경우 (미확정)

 

➡️ 주문과 할인 정책

  🔸회원은 상품을 주문할 수 있으며 등급에 따라 할인 정책 적용

  🔸모든 VIP는 1000원 고정 금액 할인(나중에 변경 가능) 

  🔸할인 정책은 변동 가능성이 높으며 오픈 직전까지 고민. 최악의 경우 할인 미적용의 가능성

 

➡️ 요구사항에서 결정을 유보한 부분은 인터페이스로 언제든 갈아낄 수 있도록 설계

 

 

 

 

 

회원 도메인 설계

 

 

➡️ 회원 도메인 요구사항

  🔸회원 가입과 조회 가능

  🔸회원 등급은 일반과 VIP 두가지

  🔸회원 데이터는 자체 DB 구축, 외부 시스템과 연동 두 가지의 경우 (미확정)

 

➡️회원 도메인 협력 관계

 

 

➡️ 회원 클래스 다이어그램

 

 

➡️ 회원 객체 다이어그램

 

 

 

 

회원 도메인 개발

 

 

 

➡️ 도메인 설계에 따라 클래스와 인터페이스 구현

package hello.core.member;

public enum Grade {
    BASIC,
    VIP
}

package hello.core.member;

public class Member {
    private Long id;
    private String name;
    private Grade grade;

    public Member(Long id, String name, Grade grade) {
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

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

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }


}
package hello.core.member;

public interface MemberService {

    void join(Member member);

    Member findMember(Long memberId);
}
package hello.core.member;

public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository =new MemoryMemberRepository();

    @Override
    public void join(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }
}
package hello.core.member;

public interface MemberRepository {

    void save(Member member);

    Member findById(Long MemberId);
}
package hello.core.member;

import java.util.HashMap;
import java.util.Map;

public class MemoryMemberRepository implements MemberRepository{

    private static Map<Long, Member> store = new HashMap<>();

    @Override
    public void save(Member member) {
        store.put(member.getId(), member);
    }

    @Override
    public Member findById(Long MemberId) {
        return store.get(MemberId);
    }
}

 

 

 

 

회원 도메인 실행과 테스트

 

 

➡️ 메인메서드로 테스트 >> 좋은 테스트X / 한계가 존재

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;

public class MemberApp {
    public static void main(String[] args) {
        MemberService memberService = new MemberServiceImpl();
        Member member = new Member(1L, "memberA", Grade.VIP);
        memberService.join(member); //회원가입

        Member findMember = memberService.findMember(1L);
        System.out.println("member = " + member.getName());
        System.out.println("findMember = " + findMember.getName());
    }
}

➡️ 

 

 

 

➡️ JUnit을 이용한 테스트

  🔸오류 또는 실패시 해당 부분 발견하기 용이

package hello.core.member;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class MemberServiceTest {

    MemberService memberService = new MemberServiceImpl();

    @Test
    void join(){
        // given : 이런 환경에서
        Member member = new Member(1L, "memberA", Grade.VIP);

        // when : 했을때
        memberService.join(member);
        Member findMember = memberService.findMember(1L);

        // then : 이렇게 된다
        Assertions.assertThat(member).isEqualTo(findMember);

    }
}

 

➡️ 회원 도메인 설계의 문제점

  🔸OCP 원칙 준수 여부, DIP 준수 여부

  🔸의존 관계가 인터페이스 뿐만 아니라 구현까지 모두 의존하는 문제점이 있음