이번 미션에서 DB에 Station 객체들을 저장하기 위해 다음과 같은 클래스를 만들었다.
DbStationRepository
@Repository
public class DbStationRepository {
private final StationDao stationDao;
public DbStationRepository(StationDao stationDao) {
this.stationDao = stationDao;
}
public long create(Station station) {
return stationDao.insert(new StationEntity(station.getName()));
}
public Station findById(Long id) {
StationEntity stationEntity = stationDao.findById(id);
return new Station(stationEntity.getId(), stationEntity.getName());
}
...
}
그럼 이 DbStationRepository
는 어떤 계층에 속해야 할까?
Domain-Driven Design (Evans, 2003)에서는 Repository
를 다음과 같이 설명하고 있다.
"a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects"
Repository
는 객체 collection의 상태를 관리하는 저장소라고 볼 수 있다.
객체 collection에 객체를 저장하고, 탐색하는 기능을 캡슐화한 것이 Repository
이다.
여기서 분명한 것은 Repository
는 객체 collection에 대한 관리를 하므로, 도메인 계층에 대해 알고있어야 한다는 것이다. 하지만, DbStationRepository
를 보면 Dao
를 사용해 영속성 계층에 접근하는 것을 볼 수 있다.
그럼 Repository
는 도메인 계층과 영속성 계층 둘 모두에 접근하고 있는 걸까?
레이어드 아키텍처 구조에 따르면, 상위 계층은 하위 계층에 대한 정보를 알고 있지만, 하위 계층에 상위 계층에 대한 정보를 알지 못한다. 의존성의 흐름이 한 방향으로 흘러야하는 것이다.
하지만 Repository
가 도메인 계층과 영속성 계층 둘 모두를 알고있다면 이 구조가 깨지게 된다.
여기서, Repository
에 의존 역전 원칙을 사용하면 의존성의 방향을 일정하게 유지할 수 있다.
추상화 객체인 StationRepository
를 생성해서 도메인 계층과 영속성 계층간의 의존을 끊는 것이다.
public interface StationRepository {
long create(Station station);
Station findById(Long id);
List<Station> findAll();
void update(Station station);
void deleteById(Long id);
}
StationRepository
를 생성한다.StationRepository
는 영속성 계층에 대한 정보를 가지고 있지 않는다. 온전히 객체 collection 관리에 대한 책임만을 가진다.
@Repository
public class DbStationRepository implements StationRepository {
private final StationDao stationDao;
public DbStationRepository(StationDao stationDao) {
this.stationDao = stationDao;
}
@Override
public long create(Station station) {
return stationDao.insert(new StationEntity(station.getName()));
}
@Override
public Station findById(Long id) {
StationEntity stationEntity = stationDao.findById(id);
return new Station(stationEntity.getId(), stationEntity.getName());
}
...
}
StationRepository
를 구현하는 DbStationRepository
를 만든다.DbStationRepository
는 Dao를 사용해 객체를 관리하는 책임을 가지므로 영속성 계층에 속한다.
하지만, StationRepository
자체는 구현체인 DbStationRepository
가 영속성 계층에 접근한다는 사실을 알지 못한다. StationRepository
는 단순히 객체 collection에 대한 관리를 추상화한 객체이며, DbStationRepository
는 객체 collection을 관리하기 위한 방법으로 객체를 DB에 저장하는 방식을 선택했을 뿐이다.
구조를 그리면 다음과 같다.
StationRepository
라는 추상화 객체를 사용해 도메인 계층과 영속성 계층간의 의존성을 역전함으로써, StationRepository
가 영속성 계층에 의존하지 않도록 관리할 수 있다.
오 글 좋은데요!!