ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] 서비스 레이어 리팩터링하기
    스터디 & 프로젝트/Mineme 프로젝트 2023. 3. 15. 20:38

    늘 일을 벌이는 나다. 욕심만 그득그득해서 그런가보다.

    사이드 프로젝트하면서 내가 구현한 비즈니스 로직을 함께 협업하는 친구 개발자에게 전달해야 했다.

    내가 맡은 파트에서 구현된 메서드를 래핑해서 사용하고자 하는데 거기에 요구한 클래스와 메서드 인터페이스는 유지해달라는 요청이 있었다.

    그에 따라서 내가 어떠한 방식으로 메서드를 추가하고 어떻게 구조를 변경하는 편이 좋을지 고민했다.

     


    요구사항과 현재 상태 확인

    우선 내가 맡은 파트는 사용자, 인가 쪽 도메인이다.

    친구가 맡은 파트는 만들고자하는 서비스가 제공하는 핵심 기능 중 하나인 글 쓰기 관련 도메인이다.

    요구사항

    • 사용자가 글을 작성할 때 사용자가 정상적인(권한, 가입여부) 사용자인지 파악하는 로직이 필요
    • 사용자가 글을 작성할 때 사용자가 정상적인 상태(탈퇴 여부, 비활성화 여부 등)를 가지는지 파악하는 로직이 필요
    • 내가 작성하고 제공할 메서드를 하나의 서비스 클래스로 만들어 사용할 것.

     

    현재 상태 확인

    public interface AuthService {
        Auth.Jwt getUserDetails(Auth.SignRequest dto);
    }
    public class KakaoAuthService implements AuthService {
        ...
    }
    
    public class ApplAuthService implements AuthService {
        ...
    }

     

    • 인가를 위한 AuthService 라는 서비스 인터페이스가 존재함.
    • 카카오, 애플 인가를 사용하는 서비스 클래스가 존재하고 해당 클래스는 AuthService를 구현함.

     


    그럼 어떻게 고쳐야하나?

    우선 내가 바라본 내 코드의 문제점은 이랬다.

    1. 인터페이스에서 제공하는 메서드가 구현 클래스에서 불필요하게 중복으로 구현될 수 있다.
    2. 다른 도메인에서 인가 관련 로직이 필요할 때 Kakao, Apple 이라는 제공자에 의존성이 강해진다.

     

    사실 회원가입 이후 서비스를 이용할 시점부터 다른 도메인은 사용자가 사용하는 인가 제공자가 카카오인지 애플인지 중요하지 않다.

     

    그런데 이런 비즈니스 로직을 래핑해서 사용할 수도 있겠지만 결국 타 도메인에서 인가 제공자마다의 인터페이스에 따라 다른 로직을 구현해야하는게 문제고 이런 정보는 타 도메인의 관점에서 은닉시키는게 맞다고 생각했다.

    내가 제공할 것은 추상화된 하나의 클래스이자 노출시킬 인터페이스만 제공하면 된다.

     


    그래서 어떻게 고쳤나?

    @Component
    @RequiredArgsConstructor
    public abstract class AuthService<T> {
        public abstract Auth.Jwt getUserDetails(T dto);
        ...
    }
    @Service
    public class KakaoAuthService extends AuthService<Auth.SignRequest> {
        ...
    }
    
    @Service
    public class AppleAuthService extends AuthService<Apple.SignRequest> {
        ...
    }

     

    우선 첫 번째.

    중복으로 구현해야 하는 로직을 AuthService에 몰아서 구현했다.

    또한, 인터페이스로 작성된 서비스를 추상 클래스로 변경했다.

     

    두 번째.

    추상 클래스에 제네릭을 도입했다.

    카카오 인가나 애플 인가에서 전달받는 DTO가 갖는 프로퍼티의 수나 내용이 달랐고 이를 별개로 적용해야 했다.

    따라서 해당 부분은 인가 도메인의 서비스 계층에서 직접 구현해 사용하도록 했다.

     


    결론

    사실 아직 부족해보인다.

    AuthService의 로직을 타 도메인에서 상속받거나 하는 등으로 책임을 떠넘기고 싶었지만 완벽하게 리팩터링한거 같지는 않다.

     

    그래도 개발은 계속 할테니 눈에 보이는게 있다면 하나 둘 바꿔봐야겠다.

    이런거 하나하나 개선해나가는게 은근히 성취감이 있다.

    댓글

Designed by Tistory.