책/도메인 주도 설계 철저 입문

[도메인 주도 설계 철저 입문] 5. 레파지토리 - 데이터와 관계된 처리를 분리하자

동현 유 2022. 3. 8. 19:23

프로그램을 실행할 때, 메모리에 로드된 데이터는 프로그램을 종료하면 그대로 사라져버린다.

 

특히 엔티티생애주기를 갖는 개체이기 때문에 프로그램의 종료와 함께 사라지면 안된다.

 

이를 위해서는 데이터를 데이터스토어에 저장하고 불러올 수 있어야한다.

 

데이터스토어로부터 불러오고, 저장하는 등의 행위를 추상화한 객체가 레파지토리 객체이다.

 

 


레파지토리의 역할과 책임

 

레파지토리 객체는 도메인 개념으로부터 유래한 것이 아니라,

 

기술적 문제를 해결하기 위해 탄생한 객체이다.

 

따라서 도메인을 잘 서술한 코드를 헤집어놓지 않으면서, 기술적 코드를 잘 분리해는 역할을 담당한다고 볼 수 있다.

 

특히 특정 db 에 의존적일 수 밖에 없는데, 이 때문에 더 다루기 까다롭게 되는 코드가 되어버릴 때가 많다.

 

그래서 레파지토리 객체를 "불러오기 load(), 저장하기 save()" 등의 추상화한 행동으로 규정한 후

 

실제 기술적 코드는 레파지토리가 수행하고, 

 

비지니스 로직에서는, 어떤 행동을 하는지만 쉽게 알 수 있다

 


레파지토리 인터페이스 정의하기

작은 프로젝트라면 하나의 db 만 사용할 수 있지만, 

 

서비스 규모가 커지다 보면 여러 db 를 사용해야하는 경우가 생길 수 있다.

 

서비스 코드는 특정 인프라에 종속적이면 안되므로,

 

db 의 종류의 상관없이, 도메인 모델 객체를 저장,삭제,수정,불러오기 등의 추상화된 인터페이스를 제공하고,

 

db 종류에 맞게 구현된 구현체를 이용해야한다.

 

Interface repository {

    void save(Entity entity);
    
    void update(Entity entity);
    
    void delete(Integer id);
    
    Entity findById(Integer id);
    
}
Class MysqlRepository implements repository {

    @Override
    public void save(Entity entity) {
    
    }
    
    @Override 
    public void update(Entity entity) {
    
    }
    
    @Override
    public void delete(Integer id) {
    
    }
    
    @Override
    public Entity findbyId(Integer id) {
    
    }
}

Class MongoRepository implements repository {

    @Override
    public void save(Entity entity) {
    
    }
    
    @Override 
    public void update(Entity entity) {
    
    }
    
    @Override
    public void delete(Integer id) {
    
    }
    
    @Override
    public Entity findbyId(Integer id) {
    
    }
}
Class EntityService {

	private final Repository repository;
    
    public EntityService(Repository repository) {
        this.repository = repository;
    }
    
    public Entity getEntity(Integer id) {
        return repository.findById(id);
    }
}

 

위와 같이 서비스와 레파지토리가 작성되어 있다고 하자

그러면 아래처럼 메인코드를 작성할 수 있다.

 

Repository repository = new MysqlRepository();
// Repository repository = new MongoRepository();

EntityService entityService = new EntityService(repository);

entityService.getEntity(1);

즉 비지니스 로직에서는 추상화된 레파지토리의 행동만 알면 되고,

 

구현체는 그때그때 필요한 것을 끼워 넣으면 되는 것이다.