DTO, DAO, VO 개념 정리

LeeYulhee·2023년 8월 28일
0

👉 DTO(Data Transfer Object)


  • 설명

    • 데이터를 전송하기 위한 객체
    • 주로 계층 간의 데이터 교환을 위해 사용
  • 사용하는 이유

    • 계층 간의 결합도를 낮추기 위해
      • Entity는 비즈니스 로직과 DB와의 연동 로직을 포함할 수 있음
      • 이를 직접 프레젠테이션 계층에 노출하는 것은 좋지 않음
      • DTO를 사용하면 Entity의 변경이 프레젠테이션 계층까지 영향을 주지 않게 할 수 있음
    • 필요한 데이터만 전송하기 위해
      • UI에서 필요한 데이터와 DB에서 저장된 데이터는 항상 일치하지 않을 수 있음
      • DTO를 사용하면 필요한 데이터만 선택적으로 전송할 수 있음
    • 보안
      • 비밀번호와 같은 민감한 정보가 Entity에 포함되어 있을 때, 이 정보를 UI에 직접 노출하는 것은 위험
      • DTO를 통해 이런 정보를 제외하고 전달할 수 있음
  • 예시

    • 프레젠테이션 계층(웹 페이지나 앱 화면)에서 사용될 데이터를 서비스 계층이나 데이터 접근 계층에서 가져올 때 이를 위한 포맷으로 DTO를 사용하곤 함
    • 사용자의 정보를 화면에 보여주기 위한 DTO
      public class UserDTO {
          private Long id;
          private String username;
          private String email;
      
          // getters, setters, constructors 등
      }


👉 Entity와 DTO의 차이


  • 📌 Entity

    • 의미
      • Entity는 주로 데이터베이스와 직접 연결된, ORM(Object-Relational Mapping)에서 사용되는 용어
      • Entity는 데이터베이스의 테이블과 1:1로 매칭되는 객체를 의미
    • 생명주기
      • Entity는 데이터베이스의 생명주기와 동일
      • 즉, 데이터베이스에 저장되거나 수정, 삭제될 때 해당 Entity도 함께 저장, 수정, 삭제됨
    • 비즈니스 로직
      • Entity는 도메인 로직을 포함할 수 있음
      • 예를 들어, 사용자 엔터티의 경우, 비밀번호 변경 로직이 포함될 수 있음
    • 식별자
      • Entity는 대개 유일한 식별자(예: ID)를 가짐
    • 사용하는 이유
      • 데이터베이스의 테이블을 객체 지향적으로 다루기 위해
      • Entity를 통해 DB의 테이블과 직접적인 연동이 가능
  • 📌 DTO (Data Transfer Object)

    • 의미
      • DTO는 계층 간 데이터 교환을 위한 객체
      • 주로 사용자 인터페이스와 서비스 또는 서비스와 데이터 액세스 계층 사이에서 데이터를 전달하는 데 사용
    • 생명주기
      • DTO는 일시적이며, 특정 로직의 호출에 대한 요청과 응답에서만 존재
      • 데이터베이스의 생명주기와는 독립적
    • 비즈니스 로직
      • 일반적으로 DTO는 로직을 포함하지 않음
      • 순수한 데이터 구조로만 구성
    • 식별자
      • DTO는 필요에 따라 식별자를 가질 수도 있고 가지지 않을 수도 있음



👉 Entity를 직접 노출하는 것이 좋지 않은 이유


  • 캡슐화 위반
    • 객체 지향 프로그래밍의 원칙 중 하나는 캡슐화
    • 이는 객체의 내부 상태와 로직을 외부로부터 보호하고, 필요한 정보와 기능만을 제공하는 것을 의미
    • 프레젠테이션 계층에 Entity를 직접 노출하면, Entity의 내부 구조나 비즈니스 로직이 노출될 위험이 있음
  • 계층 간의 강한 결합
    • 프레젠테이션 계층과 비즈니스 로직이나 데이터 액세스 로직이 강하게 결합됨
    • 이로 인해, 비즈니스 로직이나 데이터베이스 스키마에 변화가 생겼을 때, 프레젠테이션 계층도 영향을 받게 됨
    • 이는 유지 보수를 어렵게 만들며, 코드의 변화에 대한 영향도를 증가시킴
  • 데이터 무결성 문제
    • 프레젠테이션 계층에서 Entity를 직접 조작하게 되면, 실수나 보안 문제로 인해 데이터의 무결성이 손상될 가능성이 있음
  • 성능 문제
    • Entity는 데이터베이스와의 연동을 위한 객체
    • 프레젠테이션 계층에서 이를 직접 사용하게 되면, 예기치 않은 데이터베이스 액세스나 연산이 발생할 수 있음
    • 이는 시스템의 성능에 부정적인 영향을 줄 수 있음
  • 보안 문제
    • Entity가 민감한 정보(예: 비밀번호, 개인정보 등)를 포함하고 있다면, 프레젠테이션 계층에 노출되는 것은 큰 보안 위험을 수반
  • ⇒ DTO와 같은 중간 객체를 통해 필요한 정보만을 전달하고, 계층 간의 결합도를 최소화하는 것이 좋음



👉 DAO(Data Access Object)


  • 설명

    • 데이터베이스의 CRUD(Create, Read, Update, Delete) 연산을 캡슐화하는 객체
    • 이를 통해 데이터베이스에 접근하는 로직과 비즈니스 로직을 분리할 수 있음
  • 사용하는 이유

    • 데이터 접근 로직의 중복 제거
      • DAO를 사용하면 같은 데이터 접근 로직을 여러 번 작성할 필요가 없음
    • 데이터 소스의 추상화
      • 데이터베이스의 변경 (예: MySQL에서 PostgreSQL로의 변경)이 발생하더라도 DAO 인터페이스는 동일하게 유지될 수 있음
      • 이는 데이터 소스의 변경에 따른 영향을 최소화하게 해주기 때문
  • 예시

    • 사용자 정보를 데이터베이스에서 가져오거나 저장하는 DAO
      public class UserDAO {
          private DataSource dataSource;
      
          public UserDTO getUserById(Long id) {
              // 데이터베이스에서 id를 사용하여 사용자 정보를 가져오는 로직
              // 가져온 데이터로 UserDTO 객체를 생성하여 반환
          }
      
          public void saveUser(UserDTO user) {
              // UserDTO 정보를 데이터베이스에 저장하는 로직
          }
      
          // 다른 CRUD 연산 메서드들...
      }


👉 DTO와 DAO의 동작 방식 및 특징


  • 동작 방식
    • 웹 페이지나 앱에서 특정 사용자의 정보를 요청하면, 해당 요청은 서버의 서비스 계층으로 전달
    • 서비스 계층은 UserDAO를 사용하여 데이터베이스에서 사용자 정보를 가져옴
    • 가져온 사용자 정보는 UserDTO 객체로 변환
    • UserDTO 객체는 프레젠테이션 계층으로 전달되어 사용자에게 보여짐
  • 특징
    • DTO와 DAO는 웹 애플리케이션에서 데이터를 깔끔하게 처리하고 전달하는 중요한 역할
    • DTO는 데이터의 포맷이나 구조를, DAO는 데이터베이스 연산을 캡슐화하여 각 계층간의 결합도를 낮춤



👉 VO(Value Object)


  • 설명

    • 값을 표현하기 위한 객체
  • 특징

    • 불변성 (Immutability)
      • 일단 VO가 생성되면 그 상태를 변경할 수 없어야 함
      • 만약 다른 값을 가진 VO가 필요하다면, 새로운 VO를 생성해야 함
    • 동등성 (Equality)
      • VO는 동일성이 아닌 동등성에 기반해 비교되어야 함
      • 즉, 두 VO 객체가 메모리상에서 다른 위치에 있더라도, 그 내부의 값이 같다면 두 객체는 동일하다고 간주됨
  • 예시

    public final class Money {
        private final double amount;
    
        public Money(double amount) {
            this.amount = amount;
        }
    
        public double getAmount() {
            return amount;
        }
    
        // VO의 동등성을 검사하기 위한 equals() 메서드 오버라이드
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            Money money = (Money) obj;
            return Double.compare(money.amount, amount) == 0;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(amount);
        }
    }
    • Money 클래스는 불변성을 가지며, equals() 메서드를 통해 내부의 값(amount)을 기반으로 동등성을 확인



👉 VO vs DTO


  • VO (Value Object)
    • 값 자체의 의미를 중심으로 설계되며, 불변성을 가져야 함
    • 주로 도메인 로직에서 사용
    • 도메인의 핵심 로직과 밀접하게 연관되어 있고, 객체 지향적인 설계 원칙을 따름
  • DTO (Data Transfer Object)
    • 다양한 계층 간의 데이터 전송을 목적으로 설계
    • 주로 프레젠테이션 계층과 서비스 계층 간의 데이터 전달에 사용
    • VO와 달리 상태 변경이 가능
    • 단순히 데이터의 전달을 목적으로 하므로 내부 로직이 거의 없음
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글