WIPIVERSE

데이터 접근 객체

정의
데이터 접근 객체(Data Access Object, DAO)는 애플리케이션 로직과 데이터 저장소(예: 관계형 데이터베이스, 파일 시스템, NoSQL 스토어) 사이의 중재 역할을 수행하는 설계 패턴이다. DAO는 데이터베이스와 직접적인 SQL 문 또는 API 호출을 캡슐화하여, 비즈니스 로직이 구체적인 데이터 접근 방법에 의존하지 않도록 한다.

주요 목적

  1. 관심사의 분리(Separation of Concerns) – 비즈니스 로직과 영속성 로직을 분리함으로써 코드 유지보수성을 높인다.
  2. 재사용성 – 동일한 데이터 접근 로직을 여러 서비스나 모듈에서 공유할 수 있다.
  3. 교체 용이성 – 데이터베이스 종류나 영속성 프레임워크를 변경할 때 DAO 구현만 교체하면 되므로, 애플리케이션의 다른 부분에 미치는 영향을 최소화한다.
  4. 테스트 용이성 – DAO 인터페이스를 모킹(Mock)하거나 스텁(Stub)으로 교체함으로써 비즈니스 로직 단위 테스트가 가능해진다.

구조

  • DAO 인터페이스: create, read, update, delete(CRUD)와 같은 기본 운영 메서드를 선언한다.
  • 구현 클래스: 인터페이스를 구현하며, 실제 SQL 문, ORM 매핑, 혹은 외부 API 호출을 수행한다.
  • 데이터 전송 객체(Data Transfer Object, DTO): DAO와 비즈니스 로직 사이에서 데이터를 운반하는 객체이다. DTO는 보통 단순히 필드와 접근자(get/set)만을 포함한다.

사용 예시 (Java)

public interface UserDao {
    User findById(int id);
    List<User> findAll();
    void insert(User user);
    void update(User user);
    void delete(int id);
}
public class UserDaoImpl implements UserDao {
    private final DataSource dataSource;

    public UserDaoImpl(DataSource ds) {
        this.dataSource = ds;
    }

    @Override
    public User findById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        try (Connection con = dataSource.getConnection();
             PreparedStatement ps = con.prepareStatement(sql)) {
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                return new User(rs.getInt("id"),
                                rs.getString("name"),
                                rs.getString("email"));
            }
            return null;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    // 다른 메서드도 유사하게 구현
}

역사·배경

  • DAO 패턴은 1990년대 초반 객체지향 설계 원칙 중 하나인 *객체‑관계 매핑(ORM)*과 함께 널리 채택되었다.
  • 마이클 에반스(Michael Evans)의 Pattern-Oriented Software Architecture 시리즈와 같은 초기 디자인 패턴 서적에서 개념이 정형화되었다.
  • Java EE, .NET, Python(Django ORM), Ruby on Rails 등 다양한 플랫폼에서 표준적인 영속성 레이어 설계 방법으로 채택되고 있다.

관련 패턴

  • Repository 패턴: DAO와 유사하지만 도메인 모델 중심의 추상화를 강조한다.
  • Service Layer: 비즈니스 로직을 캡슐화하며, DAO를 호출한다.
  • Unit of Work: 트랜잭션 관리를 책임지고, 여러 DAO 작업을 하나의 작업 단위로 묶는다.

장점과 한계

장점 한계
코드 가독성·유지보수성 향상 작은 프로젝트에서는 과도한 추상화가 오히려 복잡도 증가
데이터베이스 교체 시 영향 최소화 인터페이스·구현 간 매핑 유지 관리 필요
테스트용 목 객체 제공 용이 구현에 따라 성능 오버헤드 발생 가능(특히 불필요한 레이어 추가 시)

결론
데이터 접근 객체는 소프트웨어 시스템에서 영속성 로직을 체계화하고, 비즈니스 로직과 데이터 저장소 간 결합도를 낮추는 데 핵심적인 역할을 수행한다. 적절히 설계·구현된 DAO는 시스템의 확장성, 테스트 가능성, 유지보수성을 크게 향상시킬 수 있다.

둘러보기

더 찾아볼 만한 주제

    전체 문서 보기