Backend
Algorithm
Project
codesche’s blog
/
Education
/
토비의 스프링 6
Backend
Algorithm
Project
codesche’s blog
/
Education
/
토비의 스프링 6
Share
Backend
Algorithm
Project
토비의 스프링 6
생성일
2025/01/24 05:52
태그
inflearn
게시일
토비의 스프링 6
Search
오브젝트와 의존관계
Spring 개념, 이론
•
관심사의 분리 (Separation of Concerns - SoC)
•
메소드 추출 - option + command + m
•
참고정보
관심사의 분리
•
하나의 클래스 안에 두 가지 관심사가 여전히 남아있다는 문제를 확인한 이후 좀 더 유연하게 확장하여Payment 서비스 자체는 재사용이 가능하도록 개선하는 작업을 수행
상속을 통한 확장
•
상속을 통해서 클래스 계층 구조 하나를 유지하는 게 아니고 클래스를 안전하게 분리시킨다.
•
Payment를 준비하는 클래스와 환율 정보를 가져오는 클래스를 완전히 독립적인 클래스로 만든다.
클래스의 분리
•
상속이 가진 문제 때문에 클래스를 분리함
•
상속을 쓰지 않고 이름을 통일하고 싶은 경우 →
인터페이스 도입
인터페이스 도입
•
PaymentService - ExRateProvider, WebApiExRateProvider 의존
관계설정 책임의 분리
•
Client는 두 개의 관심사를 가지고 있다. ⇒ 분리가 필요함
•
웹 같은 경우 해당 Client가 컨트롤러가 될 수도 있다.
•
관심사 분리 - 다음과 같이 분리한다.
•
Client가 사용할 PaymentService를 얻어온다. (ObjectFactory 생성)
오브젝트 팩토리
•
개방 폐쇄 원칙(Open-Closed Principle-OCP
)
•
높은 응집도와 낮은 결합도(High Coherence and low coupling)
•
전략 패턴
•
제어의 역전(Inversion of Control)
원칙과 패턴
•
DI(Dependency Injection) - 의존관계 주입(의존관계를 외부에서 주입해준다)
•
현재 코드 구조 상황
•
현재 진행 상황
•
스프링 IoC/DI 컨테이너 적용 후 구조도 확인
스프링 컨테이너와 의존관계 주입 (DI)
•
스프링 컨테이너가 하는 역할
•
스프링은 많은 경우 그 안에서 생성하고 구성하는 오브젝트들을 싱글톤으로 만든다.
•
하나를 만들어서 여러 사용자에 걸쳐서 공유할 수 있도록 만들어준다.
•
스프링 안에서 만들어지는 Bean 오브젝트는 딱 한 개 즉, 스프링은 싱글톤 레지스트리 역할을 한다. (스프링 안에서 만들어지는 빈 오브젝트는 딱 한 개만 만들어져서 이 빈 프로젝트를 사용하는 다른 오브젝트가 여러 개가 된다 할지라도 동일반 오브젝트가 사용된다!)
싱글톤 레지스트리
•
오브젝트 합성을 이용하는 디자인 패턴을 적용할 때 스프링의 의존관계 주입(Dependency Injection)을 사용한다.
•
데코레이터(Decorator) 디자인 패턴
DI와 디자인 패턴
의존성 역전 원칙 (Dependency Inversion Principle)
•
상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.
•
추상화는 구체적인 사항에 의존해서는 안 된다. 구체적인 사항은 추상화에 의존해야 한다.
•
모듈:
•
현재 모듈 구성도
•
일반적인 의존관계는 상위에서 하위로 만들어진다.
•
추상화? ⇒ 인터페이스를 도입하는 것이다.
•
상위 수준의 모듈은 하위 수준의 모듈에 의존하면 안 된다!
•
인터페이스 소유권 역전 후 - 의존성 역전 원칙 적용 (인터페이스 만든 후 추상화 시킴)
의존성 역전 원칙
수동 테스트의 한계
•
프린트된 메시지를 수동으로 확인하는 방법은 불편하다.
•
사용자 웹 UI까지 개발한 뒤에 확인하는 방법은 테스트가 실패했을 때 확인할 코드가 많다.
•
테스트할 대상이 많아질 수록 검증하는데 시간이 많이 걸리고 부정확함.
작은 크기의 자동 수행되는 테스트(Automated Test)
•
개발자가 만드는 테스트 - 매우 중요!
•
개발한 코드에 대한 검증 기능을 코드로 작성한다.
•
자동으로 테스트를 수행하고 결과를 확인한다.
•
테스팅 프레임워크를 활용한다.
•
테스트 작성과 실행도 개발 과정의 일부이다.
자동으로 수행되는 테스트
•
JUnit 5
JUnit 테스트 작성
요구사항 정리
PaymentService 테스트
문제점
1.
우리가 제어할 수 없는 외부 시스템에 문제가 생기면?
2.
ExRateProvider가 제공하는 환율 값으로 계산한 것인가?
3.
환율 유효 시간 계산은 정확한 것인가?
테스트의 구성 요소
•
테스트 대상 (SUT - System Under Test)
•
테스트 오브젝트 참여
•
어떤 경우에는 협력자(Collaborator)들이 붙기도 한다.
외부에 제약을 덜 받게 해주는 방법 - 의존관계 주입하여 진행
PaymentService 테스트 문제점
•
해당 테스트 코드의 문제
테스트와 DI (1)
수동 DI를 이용하는 테스트
•
테스트용 협력자(Collaborator)/의존 오브젝트를 테스트 대상에 직접 주입하고 테스트
스프링 DI를 이용하는 테스트
•
테스트용 협력자(Collaborator)/의존 오브젝트를 스프링의 구성 정보를 이용해서 지정하고 컨테이너로부터 테스트 대상을 가져와서 테스트
테스트와 DI (2)
학습 테스트
•
직접 만들지 않은 코드, 라이브러리, 레거시 시스템에 대한 테스트
•
테스트 대상의 사용방법을 익히고 동작방식을 확인하는데 유용함
•
외부 기술, 서비스가 버전이 올라갔을 때 이전과 동일하게 동작 하는지 확인할 수 있음
•
클럭에 대한 학습 테스트 적용
학습 테스트(Learning Test)
Clock을 이용한 시간 테스트
•
도메인 모델 아키텍처 패턴
정리 - 개발자가 만드는 테스트
•
개발한 코드에 대한 검증 기능을 코드로 작성
•
자동으로 테스트를 수행하고 결과를 확인
•
테스팅 프레임워크를 활용
•
테스트 작성과 실행도 개발 과정의 일부
도메인 오브젝트 테스트
•
개방 폐쇄 원칙(OCP)
•
템플릿
다시 보는 개방 폐쇄 원칙
•
리팩터링의 전제 - 버그가 생기면 안 된다!
•
리팩터링을 잘하려면 테스트를 잘 만들어주어야 한다!
WebApiExRateProvider 리팩터링
•
WebApiExRateProvider의 구성
•
메소드 추출
변하는 코드 분리하기 - 메소드 추출
•
템플릿(Template)
•
템플릿 메소드 패턴?
•
메소드 추출 후 코드
변하지 않는 코드 분리하기 - 메소드 추출 (템플릿의 탄생)
•
ApiExecutor 인터페이스 생성
•
SimpleApiExecutor 클래스 생성
•
WebApiExrateProvider 수정
ApiExecutor 분리 - 인터페이스 도입과 클래스 분리
•
콜백(Callback)
•
템플릿/콜백은 전략 패턴의 특별한 케이스
•
메소드 주입
•
템플릿/콜백의 작업 흐름
ApiExecutor 콜백과 메소드 주입 (Callback + Method Injection)
•
템플릿/콜백의 작업 흐름
ExrateExtractor 콜백
•
ApiTemplate
•
ApiTemplate
•
HttpClientApiExecutor
•
WebApiExRateProvider
ApiTemplate 분리 - 환율정보 API의 기본 틀