미확정 부분도 개발을 무기한 기다릴수 없으니 interface를 만들고 구현체를 다시 만드는 방식으로 설계하도록 하겠다.
회원 도메인 협력 관계
회원 클래스 다이어그램
회원 등급
package com.example.springex1.member;
public enum Grade {
BASIC,
VIP
}
회원 엔티티
package com.example.springex1.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 com.example.springex1.member;
public interface MemberRepository {
void save(Member member);
Member findById(Long memberId);
}
메모리 회원 저장소 구현체
package com.example.springex1.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);
}
}
회원 서비스 인터페이스
package com.example.springex1.member;
public interface MemberService {
void join(Member member);
Member findMember(Long memberId);
}
회원 서비스 구현체
package com.example.springex1.member;
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
public void join(Member member) {
memberRepository.save(member);
}
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
package com.example.springex1.member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
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를 잘 지키고 있을까?
--> 의존관계가 인터페이스 뿐만 아니라 구현까지 모두 의존하는 문제점이 있다.
--> 주문까지 만들고나서 문제점과 해결 방안에 대해 알아보겠다.
참고
김영한: 스프링 핵심 원리 - 기본편(인프런)
Github - https://github.com/b2b2004/Spring_ex