새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.
Service는 어디까지 책임져야하나
목표 D-day : 31 일
스프링 MVC 패턴과 @Controller
,@Service
컴포넌트의 역할 정의를 학습합니다.
먼저 자바와 스프링은 객체지향 프로그래밍 방식으로 코드를 작성하길 원합니다.
그러면 객체로 볼때 @Service
의 역할은 어디까지인지 알아야 책임을 분리할 수 있다고 생각해서 학습을 합니다.
학습 목표
- 서비스란 뭘까?
- 서비스는 왜 서비스라고 불릴까?
- 정리
서비스
서비스 레이어 역할을 표시하는 @Service
컴포넌트에는 비즈니스 로직이 들어가야 한다고 합니다.
스마트 컨트롤러는 개발은 빠르고 가독성도 좋다는 장점이 있지만, 추가 요청 사항이나 코드가 길어진다면 유지보수나 확장 및 재사용이 어렵습니다.
중복 코드가 발생하고 커스텀된 매서드로 변경될 수 있으므로 공통된 로직으로 분리하기 어려워집니다.
그래서 비즈니스 로직을 서비스 계층에 밀어 넣고, @Transaction
애노테이션을 추가하여 해당 로직이 원자성을 보장하도록 하도록 합니다.
서비스는 트랜잭션 스크립트를 주의해야한다.
회원이 물건을 구매하는 서비스 로직을 작성해보겠습니다.
@Transaction
public BuyResponse buyProduct(BuyRequest request){
// 회원 조회
// 회원 정보 검증 - 비즈니스 정책 검증
// 물품 조회
// 물품 정보 검증 - 재고가 있는지 확인
// 회원 쿠폰 조회
// 최종 가격 = 물품정보 * 쿠폰 할인률
// ...
// 회원 정보 저장, 물품 정보 저장, 쿠폰 정보 저장
}
컨트롤러에 작성된 비즈니스 로직이 그대로 트랜잭션만 추가되어 원자성이 보장되는 절차적 프로그래밍 스크립트가 되어버린 상황입니다.
이렇게 되면 청소하기 싫어서, 개발을 빨리하려고 잘 안 보이는 곳에 밀어 넣은 구조가 되어버린다고 생각합니다.
이렇게 되면 서비스 로직도 스마트 컨트롤러처럼 유지보수와 확장이 어려운 안티패턴으로 바뀔 수 있습니다.
@서비스란
@Service
애노테이션 주석을 확인해보면 알 수 있습니다.
서비스는 도메인 주도 설계에서 시작된 개념으로,캡슐화된 상태 없이, 모델과는 독립적인 동작을 제공하는 인터페이스 입니다.
이 애노테이션이 지정된 클래스는 J2EE 패턴 중 하나인
비즈니스 서비스 파사드
나 그와 유사한 것처럼 사용될 수 있음을 의미합니다.이 애노테이션은 매우 일반적인 용어로 각자의 사정에 맞게 의미를 좁혀 사용할 수 있습니다.
주석을 정리하면
- 도메인 주도 설계 개념에서 만들어진 애노테이션
- 서비스는 J2EE 패턴 중 하나인 비즈니스 서비스 파사드처럼 사용될 수 있다.
도메인 주도 설계
도메인 주도 설계는 도메인을 중심에 두고 소프트웨어를 설계하는 방법을 말합니다.
도메인이란 비즈니스 영역
이다. 라고 합니다.
프로그래밍을 하는 이유는 문제 해결을 하기 위해서 입니다.
다시 정의를 해보면 도메인은 비즈니스(의 문제 해결을 하기 위한)영역
이라고 할 수 있습니다.
개발자는 코드만 작성하는 것이 아니라 도메인을 이해가 필요합니다.
도메인 내 모든 것을 이해하기 어려우니 실무자와 협력하여 함께 설계하는 것이 중요합니다.
이 책에서 서비스 컴포넌트(Service
)가 있습니다.
자신의 본거지를 ENTITY나 VALUE OBJECT에서 찾지 못하는 중요한 도메인 연산이 있다.
이들 중 일부는 본질적으로 사물이 아닌 활동(activity)이나 행동(action)인데, 우리의 모델링 패러다임이 객체이므로 그러한 연산도 객체와 잘 어울리게끔 노력해야 한다.
-에릭 에반스
서비스는
자신의 본거지에서 찾지 못하는 중요한 연산을 처리하는 컴포넌트라고 할 수 있습니다.
객체지향 프로그래밍은 객체끼리 통신하여 문제를 해결하는 방법입니다.
정리하면
객체(Entity)끼리 문제를 해결하기 어려운 연산을 처리하는 곳이 서비스다
목적에 따라 서비스가 다르다
서비스는 엔티티(객체)끼리 처리하기 어려운 도메인 연산을 하는 컴포넌트를 말한다고 합니다.
여기서 말하는 도메인 연산은 비즈니스 로직의 연산을 의미하며 객체 내에서 처리하기 어려운 경우를 말합니다.
객체지향 프로그래밍을 사용하는 이유를 한 줄로 정의해보면
문제(도메인)를 객체로 추상화하여 유연한 구조와 재사용성을 높여 확장성과 유지보수를 편하게 하는 것.
다시 말하면 문제를 객체로 추상화할 때 어디까지 추상화 할지 결정하는 방법에 따라 트레이드 오프가 생긴다고 생각합니다.
그러면 다시 서비스 레이어로 보면 객체끼리 해결하기 어려운 연산을 처리하는 컴포넌트가 있고
어플리케이션이 원할하게 돌아가게 하기 위한 컴포넌트가 있다고 나눌 수 있습니다.
여기서 말하는 어플리케이션 서비스는 데이터를 조회하고, 네트워크를 호출하고, 데이터를 저장하는 것을 말합니다.
비즈니스 로직과 관련이 없이 단순히 데이터를 읽고, 보내고, 저장하는 것을 말합니다.
- 애플리케이션 서비스: 애플리케이션이 원할하게 돌아가기 위해 사용되는 로직이 있는 컴포넌트
- 도메인 서비스: 객체끼리 처리하기 어려운 비즈니스 연산을 처리하는 컴포넌트
또한 비즈니스 로직이 들어간 도메인 서비스는 정책이 변경될 때 마다 변경이 필요합니다.
하지만 애플리케이션 서비스는 비즈니스 로직이 변경되어도 데이터 호출, 저장 방식은 달라지는 시점이 다릅니다.
따라서 추상화를 할 때 코드 변경 사이클이 다른 관심사는 나누는 것이 유지보수나 확장성에 좋다고 생각합니다.
정리
@Service
는 주방, 스터디 카페처럼 장소를 제공해주는 컴포넌트다.
주방, 스터디 카페에 들어온 사람들끼리 대화(통신)을 하도록 자리를 마련해주고, 필요한 정보를 가져와주는 곳을 말합니다.
스터디 카페에서 문제가 발생했는데 사용자끼리 해결하기 어려운 문제는 총무를 부르거나 매니저를 불러서 해결합니다.
매니저는 비즈니스에서 발생된 문제를 해결하기 위한 객체입니다.
다시 정리하면
- 애플리케이션 서비스 : 엔티티를 가져오고, 엔티티 기능을 호출하고, 저장하는 장소
- 도메인 서비스: 엔티티끼리 통신으로 문제를 해결하기 어려운 책임을 가지는 곳
- 엔티티(객체): 비즈니스 로직을 가지고 있으며 내부 속성이나 값을 단순히 반환하는 것이 아니라 내부 상태(필드)를 사용하여 동작하는 방식
서비스란 무엇일까?
엔티티끼리 통신으로 문제를 해결하기 어려운 책임을 가지는 곳
서비스는 왜 서비스라고 부를까?
우리(객체)가 은행(도메인)에 가서 이체(문제)를 하려고 합니다.
이체할 때 문자 서비스라는 게 있습니다. 이체 이벤트가 발생할 경우 사용자에게 결과를 확인해 볼 수 있도록 제공하는 서비스입니다.
여기서 서비스가 서비스라고 부르는 이유가 나온다고 생각합니다.
객체끼리 통신하여 해결할 수 없는 그 외의 연산을 처리하거나 장소를 빌려주는 것을 서비스라고 생각합니다.
댓글남기기