스프링의 핵심 개념을 체득하기 위해 순수 자바 기반의 예제를 만들어보며 객체 지향 설계 원칙이 실제 개발에서 어떤 의미를 가지는지 확인해보는 시간이다.
이번 포스팅에서는 회원 가입과 조회 기능을 중심으로 도메인 설계 → 구현 → 테스트까지 하나하나 살펴본다.
회원 도메인 요구사항 정리
- 회원은 가입할 수 있어야 하고, 가입한 회원을 조회할 수 있어야 한다.
- 회원은 일반과 VIP 두 가지 등급이 있다.
- 회원 정보는 자체 DB나 외부 시스템과 연동하여 저장할 수 있다. (아직 미확정)
저장소 구현이 미정인 상태이므로 개발 초기에는 메모리 기반 저장소를 사용한다.
이후 구현체만 바꿔 끼우는 구조로 설계하면 된다.
역할과 구현 분리 전략
요구사항 중에서 회원 저장 방식과 할인 정책은 변경 가능성이 크다.
그래서 다음의 객체 지향 설계 원칙을 지켜야 한다.
- DIP (Dependency Inversion Principle): 추상화(인터페이스)에 의존하고 구체화(구현체)에 의존하지 말 것
- OCP (Open-Closed Principle): 확장에는 열려있고 변경에는 닫혀있어야 함
설계 방향
- 인터페이스를 먼저 설계하고
- 구현체는 나중에 갈아끼울 수 있도록 구성
회원 도메인 클래스 구성
회원 등급 | Grade (Enum: BASIC, VIP) |
회원 정보 | Member (id, name, grade) |
저장소 인터페이스 | MemberRepository |
메모리 저장소 구현체 | MemoryMemberRepository |
회원 서비스 인터페이스 | MemberService |
회원 서비스 구현체 | MemberServiceImpl |
테스트 코드로 구조 검증
간단한 JUnit 테스트를 통해 회원 가입 및 조회 기능이 잘 동작하는지 검증할 수 있다.
@Test
void join() {
// given: 이런 상황에서
// when: 이렇게 행동했을 때
// then: 결과는 이렇다
}
설계 문제점 도출
처음 설계에서는 다음과 같은 구조적 문제가 있다.
- MemberServiceImpl이 MemoryMemberRepository에 직접 의존하고 있다.
- 이는 DIP와 OCP를 모두 위반하는 구조다.
- 저장소 구현체가 바뀌면 클라이언트 코드까지 변경해야 하는 상황이 발생한다.
해결 방향
- 인터페이스(MemberRepository)에만 의존하도록 설계를 변경해야 한다.
- 클라이언트 코드(MemberServiceImpl)는 구현체가 무엇인지 몰라야 한다.
- 이로써 확장 가능하고, 변경에 강한 구조가 된다.
객체 지향 설계 퀴즈 정리
Q1. 역할(인터페이스)과 구현(클래스)을 분리하는 이유는?
→ 구현체가 변경되더라도 사용하는 코드(역할)는 바뀌지 않아 유연하게 대처할 수 있다.
Q2. 저장소를 인터페이스로 설계한 이유는?
→ 프로젝트 도중에 인메모리 저장소에서 DB로 바뀔 수 있기 때문에 구현체를 손쉽게 교체할 수 있도록 설계한다.
Q3. JUnit 테스트의 장점은?
→ 테스트 자동화를 통해 반복 가능한 검증이 가능하고, 빠르고 정확하게 오류를 확인할 수 있다.
Q4. 구현체에 직접 의존하면 어떤 원칙을 위반하는가?
→ DIP를 위반하며, 구체 클래스에 의존하는 구조가 되어 변경에 매우 취약해진다.
마무리
이번 포스팅에서는 스프링 없이 순수 자바로 객체 지향적인 예제를 직접 구현하며, 왜 역할과 구현을 분리해야 하는지, 그리고 의존 역전 원칙과 개방-폐쇄 원칙이 어떤 의미를 가지는지를 확인해보았다.
다음 편에서는 주문 도메인을 만들고, 할인 정책을 추가하면서 진짜 객체 지향적으로 잘 설계했는지 점검해볼 예정이다.
'Spring' 카테고리의 다른 글
[Spring 완전 정복 시리즈] 8편 - AppConfig로 객체 지향 설계 완성하기 (0) | 2025.07.26 |
---|---|
[Spring 완전 정복 시리즈] 7편 - DIP/OCP 위반 구조의 문제점 (1) | 2025.07.26 |
[Spring 완전 정복 시리즈] 5편 - 객체 지향 설계와 스프링: DI가 왜 중요한가? (0) | 2025.07.23 |
[Spring 완전 정복 시리즈] 4편 - 좋은 객체 지향 설계의 5가지 원칙 (SOLID) (0) | 2025.07.23 |
[Spring 완전 정복 시리즈] 3편 - 객체 지향 특징: 유연하고 변경에 강한 코드의 시작 (6) | 2025.07.23 |