도메인 계층의 POJO를 지키지 못하는 문제해결

sion Jeong·2024년 9월 19일
0

문제상황

핵심 비즈니스 로직은 도메인 계층에 있어야 합니다.
도메인 계층이 POJO(Plain Old Java Object) 형태로 존재해야 약한 결합성을 가질 수 있으며,
나중에 스프링이 사라지거나 다른 프레임워크로 바뀌어도 코드를 재사용할 수 있습니다.

하지만, 비밀번호 인코딩 및 검증 로직은 외부 프레임워크(PasswordEncoder)에 의존하고 있었으며,
이로 인해 도메인 계층에서 외부 프레임워크에 대한 결합성이 생겼습니다.


문제 원인

  1. 비즈니스 로직의 도메인 계층 존재
    • 비밀번호 인코딩 및 검증 로직은 핵심 비즈니스 로직으로, 도메인 계층에 있어야 합니다.
  2. 외부 프레임워크 종속성
    • 비즈니스 로직이 외부 프레임워크(PasswordEncoder)에 의존하고 있었기 때문에,
      도메인 계층이 POJO로 유지되지 못하고 외부 기술 스택에 의존하게 되었습니다.

이로 인해 도메인 객체는 핵심 비즈니스 로직을 포함하고 있지만,
약한 결합과 POJO로서의 역할을 수행하지 못하는 문제가 발생했습니다.


문제 해결 과정

이 문제를 해결하기 위해 도메인 서비스 패턴을 적용했습니다.
도메인 서비스 패턴을 통해 도메인 객체는 핵심 비즈니스 로직을 수행하되,
외부 종속성을 처리하는 부분은 서비스 계층에서 담당하게 만들었습니다.
이로써 도메인 객체는 POJO로 유지되며, 외부 프레임워크에 대한 의존성은 제거되었습니다.

  1. 비즈니스 로직 분리
    • 도메인 객체는 비즈니스 로직과 상태 관리만을 담당하며,
      외부 종속성에 대한 로직은 서비스 계층에서 처리하게 했습니다.
  1. POJO 유지
    • 비즈니스 로직은 도메인 객체 내에 유지하고,
      외부 종속성 처리 로직은 도메인 서비스에서 처리함으로써
      도메인 객체가 POJO로 남을 수 있게 했습니다.

결과

도메인 계층과 서비스 계층의 분리를 통해 도메인 객체는 POJO로서의 형태를 유지하게 되었으며,
외부 종속성에 의존하는 로직은 도메인 서비스에서 처리하게 되었습니다.

  • 핵심 비즈니스 로직: UserDomain에 위치.
  • 외부 종속성을 처리: UserDomainService에서 처리하여 도메인 계층의 POJO를 유지 할 수 있습니다.
  • 변경된 도메인계층 (UserDomain)
    public class UserDomain {
    
        private Long id;
        private String nickname;
        private String password;
        private String phoneNumber;
        private String profileImageUrl;
        private Role role;
        private List<Long> ordersId;
    
        public UserDomain(Long id, String nickname, String password, String phoneNumber, String profileImageUrl, Role role, List<Long> ordersId) {
            this.id = id;
            this.nickname = nickname;
            this.password = password;
            this.phoneNumber = phoneNumber;
            this.profileImageUrl = profileImageUrl;
            this.role = role;
            this.ordersId = ordersId;
        }
    
        // 비즈니스 로직 (판매자 여부 확인)
        public boolean isSeller() {
            return this.role == Role.SELLER;
        }
    
        // 비즈니스 로직 (권한 변경)
        public void changeRole(Role newRole) {
            this.role = newRole;
        }
    
        // 비즈니스 로직 (비밀번호 확인)
        public boolean checkPassword(String rawPassword) {
            return this.password.equals(rawPassword);  // 인코딩된 비밀번호와 비교하는 로직만 유지
        }
    
  • 외부 종속성 처리를 위한 UserDomainService 추가
     @Service
     public class UserDomainService {
    
         private final PasswordEncoderUtil passwordEncoderUtil;
    
         public UserDomainService(PasswordEncoderUtil passwordEncoderUtil) {
             this.passwordEncoderUtil = passwordEncoderUtil;
         }
    
         // 비밀번호 인코딩
         public void encodePassword(UserDomain userDomain) {
             String encodedPassword = passwordEncoderUtil.encodePassword(userDomain.getPassword());
             userDomain.updatePassword(encodedPassword);
         }
    
         // 비밀번호 검증
         public boolean validatePassword(UserDomain userDomain, String rawPassword) {
             return passwordEncoderUtil.validatePassword(userDomain.getPassword(), rawPassword);
         }
     }
    
profile
개발응애입니다.

0개의 댓글