• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

역할과 구현

21.08.09 14:40 작성 조회수 277

4

안녕하세요. 방학기간을 통해 스프링에 대해 공부하고 있는 대학생입니다. 다름이 아니라 스프링 핵심원리 강의에서 역할과 구현을 분리하라고 배웠습니다.
그래서 만약 '회원 저장소'를 만든다고 하면
pubic interface MemberRepository{
void save(Member member);
Member findById(Long memberId);
}
을 만들고 필요한 구현체를 따로 만들었습니다.
메모리를 이용한다면
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);
}
}
이런 식으로 만들고, 만약 JPA를 이용한다면
public class MemberJpaRepository implements MemberRepository {
@PersistenceContext
private EntityManager em;
public void save(Member member) {
em.persist(member);
}
public Member findById(Long id) {
Member member = em.find(Member.class, id);
return member;
}
}
이런 식으로 만들어서 사용했습니다.
여기서 스프링데이터JPA를 사용하기 위해선 인터페이스에 JpaRepository를 상속받아야하는데
그러면 기존에 있던 MemberRepository에 상속받아서 사용하면 되나요?
그런데 MemberRepository에서 JpaRepository를 상속받게 되면 기존에 MemberRepository 구현체들이 JpaRepository까지 모두 구현해야하는 문제가 있고, MemberReposity에서 사용하는 메소드 이름과 JpaRepository에서 사용하는 메소드 이름이 같으면 MemberRepository를 주입받아 사용하는 다른 클래스에도 문제가 발생했습니다.
이래저래 글이 길었지만 그래서 어떻게 스프링데이터 JPA를 사용하면서 역할과 구현을 구분할 수 있을까요?

답변 1

답변을 작성해보세요.

1

안녕하세요. 가짜님 좋은 질문입니다.

이것은 사실 트레이드 오프 입니다.

스프링 데이터 JPA가 제공하는 이미 인터페이스에 정의된 편리한 기능을 그대로 가져다 쓸 수 있는 장점이 있으면서 동시에 역할과 구현이라는 유연함을 어느정도 포기해야 합니다.

그래도 할 수 있는 방법이 있는데요.

스프링 데이터 JPA를 전혀 의존하지 않는 MemberRepository 인터페이스를 만들고

MyMemberRepositoryImpl implement MemberRepository 구현체를 만들고

MyMemberRepositoryImpl 구현체에서 스프링 데이터 JPA를 의존해서 사용하는 방법입니다.

그러니까 SpringDataJpaMemberRepository(스프링 데이터 JPA) 라는 인터페이스를 만들고 가져다 사용하는 것이지요.

예제 코드는 다음과 같습니다.

class MyMemberRepositoryImpl implement MemberRepository {

  SpringDataJpaMemberRepository repository;

}

감사합니다.

가짜님의 프로필

가짜

질문자

2021.08.09

답변 감사합니다. 언제나 질문에 성실히 답해주셔서 감사합니다.

이런 고민을 하셨다는 것은 로드맵을 따라서 강의를 매우 진지하게 듣고 계신다는 생각이 드네요. 가짜님은 좋은 백엔드 개발자가 되실거에요^^ 응원합니다. 화이팅!