인프런 김영한의 스프링 입문을 듣고 작성한 글입니다
입문 강의이기에 복잡한 비지니스보단 전체적으로 알아보는 시간을 갖도록 하겠습니다
비지니스 요구사항 정리
- 데이터: 회원ID, 이름
- 기능: 회원 등록, 조회
- 아직 데이터 저장소가 선정되지 않았다는 가상의 시나리오 (스프링의 특성을 알아보기 위해)
일반적인 웹 애플리케이션 계층 구조
- 컨트롤러: 웹 MVC의 컨트롤러 역할
- 서비스: 핵심 비즈니스 로직 구현 (ex. 회원ID가 중복이 안되다는 등)
- 리포지토리: 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
- 도메인: 비지니스 도메인 객체 (ex. 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장하고 관리됨)
우리도 위와 같이 일반적인 웹 애플리케이션 계층 구조를 따라 갈 것이다
클래스 의존관계
- 아직 데이터 저장소가 선정되지 않아서, 우선 인터페이스로 구현 클래스를 변경할 수 있도록 설계
- 데이터 저장소는 RDB, NoSQL 등 다양한 저장소를 고민중인 상황으로 가정
- 개발을 진행하기 위해서 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소를 사용 함
향후에 구체적인 기술이 정해지면 바꿔끼워야 하는데, 이때 필요한 것이 바로 인터페이스이다
인터페이스가 뭔지 좀 알아봤다
인터페이스: 객체 지향 프로그래밍에서 클래스 간의 계약(Contract)또는 설계 규약을 의미 한다
인터페이스는 이 클래스는 반드시 이런 동작(메서드)를 구현해야 한다라고 명시를 한다
하나의 인터페이스를 구현하면 여러 클래스들을 만들 수 있고 코드 결합도를 낮추고, 버그가 생길 확률을 줄여준다
회원 도메인과 리포지토리 만들기
회원 객체
회원 리포지토리 인터페이스
회원 리포지토리 메모리 구현체
여기서 새로 알게된 개념들이 있다
바로 Optional과 stream 함수 부분이다
Optional을 넣기전에는 null값에 대해 그냥 반환하거나 따로 처리를 했는데
Optional은 null값이 발생할 수 있는 상황을 처리하게 사용되는 클래스로, 값이 존재하거나 존재하지 않을 때 상황을 처리하기 위해 사용된다
목적은 null을 직접 사용해서 발생하는 예외(NPE)를 예방하기 위한 방법이다
그래서 결과가 존재하면 그 값을 담아서 반환하고, 결과가 없으면 빈 Optional은 반환하게 된다
stream부분은 자바를 따로 깊게는 공부하지 못해 잘모르는 개념인 것 같아 알아보았다
일단 stream은 데이터의 연속적인 흐름을 나타내고, 저장하지 않고 데이터를 읽고 처리하기 위한 도구로 사용된다
stream은 두 가지 연산으로 나뉘는데 중간 연산, 최종 연산으로 나뉜다
중간 연산은 데이터를 변환하거나 필터링하며, 결과는 새로운 스트림을 반환한다
최종 연산은 데이터를 처리하고 결과를 생성하며, 스트림 처리가 종료 된다
그래서 우리는 중간 연산으로 filter를 통해 조건에 맞는 요소를 걸러내고
최종 연산으로 findAny를 통해 조건에 맞는 데이터 중 하나를 반환하게 된다
for, if 와 같이 저장이 필요하고 명시되는 것과 달리 stream은 데이터가 연속적인 흐름으로 처리 되는 구조라고 보면 된다
회원 리포지토리 테스트 케이스 작성
위에서 보았듯이 코드들을 작성했고 이제는 잘 동작하는 확인이 필요하기 때문에 테스트가 필요하다
이전 단계에서 구현했던 것들을 테스트 하기 위해서 테스트 케이스를 만들어 테스트 과정을 더 수월하게 진행하도록 하겠다
Assertions를 이용해서 간단하게 한개 만들어 봤고 테스트를 해 성공하면 초록불과 통과했다고 나온다
null값을 넣어 테스트가 틀리게 만들었고, 틀리면 빨간 불과 테스트가 실패했다고 뜬다
그리고 expected도 함께 나와 기대한 것은 이거지만, 실제로는 저것이 나왔다고 설명까지 해준다
여러 테스트들을 만들었을 때 store가 중복으로 사용되어 생기는 오류가 발생했다
그래서 AfterEach를 사용해서 메서드 하나를 실행할 때 afterEach도 실행되도록 우선 만들었고
clearStore라는 메서드를 하나 만들어 하나의 메서드를 실행할 때 store가 초기화 되도록 만들어 오류를 해결했다
회원 서비스 개발
이번에는 회원 서비스 클래스를 만들어 보겠다
회원 리포지토리와 도메인을 활용해서 비지니스 로직을 만들어보겠다
서비스 기능으로 회원 가입과 회원 조회 기능을 만들었다
회원 서비스 테스트
마지막으로 이제 만든 회원 서비스를 테스트 해 볼 시간이다
이번에는 보기 쉽게 따로 주석을 달아주었다
given은 ~가 주어졌을 때
when은 ~일 때
then은 그러면 무엇을 실행한다
이 구조로 나누어 코드를 작성했다
이번에는 BeforeEach를 사용해서 코드를 조금 수정했다
각 테스트 실행 전에 호출되며, 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고 의존관계도 새로 맺게 해주었다
기존에는 회원 서비스가 메모리 회원 리포지토리를 직접 생성하게 했으나
현재는 회원 서비스 코드를 DI(Dependency Injection, 의존성 주입) 가능하게 변경했다
DI는 객체 간의 의존성을 코드 내부에서 직접 생성하는 것이 아닌 외부에서 주입하는 방식이며,
장점으로 유지보수성과 테스트의 용이성이 좋아진다는 점이다!
다음 강의로 돌아오겠습니다
'Backend > Spring' 카테고리의 다른 글
[Spring] 6. 스프링 DB 접근 기술 (1) | 2025.03.06 |
---|---|
[Spring] 5.회원 관리 예제 - 웹 MVC 개발 (0) | 2025.03.02 |
[Spring] 4. 스프링 빈과 의존관계 (0) | 2025.03.02 |
[Spring] 2. 스프링 웹 개발 기초 (0) | 2025.02.18 |
[Spring] 1. 프로젝트 환경 설정 (0) | 2025.02.13 |