문제점

학습 페이지

개요

보통 웹 어플리케이션은 다음의 세가지 계층을 갖곤 한다.

image.png

여기서 가장 중요한 계층은… 바로 핵심 비즈니스 로직이 있는 서비스 계층이다. 시간이 지나면서 UI와 DB기술이 다른 기술로 변동이 되더라도

서비스 계층의 비즈니스 로직은 최대한 변경없이, 오로지 비즈니스 정책에 의해서만 변경되면서 유지되어야 한다.

사실상 데이터 접근 계층과 프리젠테이션 계층은 각각 외부의 DB기술들, Web기술들로부터 서비스 계층을 순수하게 유지시켜주기 위해 보호하는 역할을 한다고 생각할 수도 있다.

서비스 계층이 이렇게 특정 기술에 종속되지 않고 순수한 자바 코드로만 작성되어있으면 비즈니스 로직을 유지보수하기도 쉽고 테스트 하기도 쉽다.

기존 트랜잭션 방식 문제 도출

지금까지 작성한 service코드들을 한번 보자.

먼저 V1이다.

package hello.jdbc.service;

import hello.jdbc.domain.Member;
import hello.jdbc.repository.MemberRepositoryV1;
import lombok.RequiredArgsConstructor;

import java.sql.SQLException;

@RequiredArgsConstructor
public class MemberServiceV1 {

    private final MemberRepositoryV1 memberRepository;

    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        Member fromMember = memberRepository.findById(fromId);
        Member toMember = memberRepository.findById(toId);

        memberRepository.update(fromId, fromMember.getMoney() - money);
       //오류 케이스
        if(toMember.getMemberId().equals("ex")) {
            throw new IllegalStateException(("계좌이체중 문제발생"));
        }

        memberRepository.update(toId, toMember.getMoney() + money);
    }
}

이 코드는 엄청 단순하고, 오직 순수 자바 코드에만 의존하고 있다.

💡 물론 정말 순수 자바코드에만 의존하고 있는건 아니다. 우선 SQLException 은 JDBC 스펙상에 있는 예외이다. 즉, JDBC라는 기술에 의존하고 있음.

이를 막아주기 위해선, SQLException을 발생시킬 수 있는 memberRepository 단에서 이 예외를 막아줘야 한다.

또한 의존성 주입받는 타입이 인터페이스타입이 아니라 구현체의 타입이다. 이는 DIP위반임.