저장소 패턴 소개


  • 저장소 패턴은 영속성 저장소를 추상화 한 것이다. 저장소 패턴은 모든 데이터가 메모리상에 존재하는 것 처럼 가정하여 데이터 접근과 관련된 지루한 세부 사항을 감춘다.

  • 가장 간단한 저장소에는 메서드가 두 가지 밖에 없다. add()는 새 원소를 저장소에 추가하고, get()은 이전에 추가한 원소를 저장소에서 가져온다.

  • 도메인 서비스 계층에서 데이터에 접근할 때는 엄격하게 이 두가지 메서드만 사용할 수 있다. 이렇게 단순성을 강제로 유지하면 도메인 모델과 데이터베이스 사이의 결합을 끊을 수 있다.

from collections import abc

import model


class AbstractRepository(abc.ABC):

    @abc.abstractmethod
    def add(self, batch: model.Batch):
        raise NotImplementedError

    @abc.abstractmethod
    def get(self, reference) -> model.Batch:
        raise NotImplementedError

class SqlAlchemyRepository(AbstractRepository):
    def __init__(self, session):
        self.session = session

    def add(self, batch):
        self.session.add(batch)

    def get(self, reference):
        return self.session.query(model.Batch).filter_by(reference=reference).one()

    def list(self):
        return self.session.query(model.Batch).all()
  • 따라서 이런 형태의 코드가 나올 것이다. 스프링에서 JPA를 사용할 때 repository 코드와 매우 닮아 있다.

트레이드오프


  • DDD와 의존성 역전이라는 경로를 택한 이상 저장소 패턴은 이 책에서 나열한 패턴 중에서도 가장 채택하기 쉬운 패턴이다.

  • 코드만 고려한다면 저장소 패턴은 단지 SQLAlchemy 추상화 (session.query(Batch))를 우리가 직접 설계한 다른 추상화 (batches_repo.get)로 바꿔치기 한 것 밖에 되지 않는다.

테스트에 사용하는 가짜 저장소를 쉽게 만드는 방법


class FakeRepository(AbstractRepository):

    def __init__(self, batches):
        self._batches = set(batches)

    def add(self, batch):
        self._batches.add(batch)

    def get(self, reference):
        return next(b for b in self._batches if b.reference == reference)

    def list(self):
        return list(self._batches)
  • 이 클래스가 set()을 감싸는 간단한 래퍼이므로 모든 메서드는 한줄로 끝난다.

  • fake_repo = FakeRepository([batch1, batch2, batch3])

  • 추상화를 대신하는 가짜 객체를 만드는 것은 설계에 대한 피드백을 얻는 아주 좋은 방법이다.

  • 가짜 객체를 만들기 어렵다면 추상화를 너무 복잡하게 설계했기 때문일 것이다.

저장소 패턴 정리


  • ORM에 의존성 역전을 적용하자, 도메인 모델은 인프라에 대해서 걱정할 필요가 없어야 한다. ORM은 모델을 임포트해야 하며 모델이 ORM을 임포트해서는 안된다.

  • 저장소 패턴은 영속성 저장소에 대한 단순한 추상화다. 저장소는 컬렉션이 메모리 상에 있는 개체라는 환상을 제공한다. 저장소를 사용하면 핵심 애플리케이션에는 영향을 미치지 않으면서 인프라를 이루는 세부 구조를 변경하거나 목 저장소를 쉽게 작성할 수 있다.

참고 문헌


>> Home