영속성 어댑터는 다음 단계를 따릅니다.

  1. 입력받기
  2. 입력을 데이터베이스 입력 포맷으로 매핑
  3. 데이터베이스로 전송
  4. 처리 결과를 매핑
  5. 출력을 반환

먼저 유스 케이스로부터 엔티티나 데이터베이스 특정 연산 전용 객체를 입력받습니다. 영속성 어댑터는 받은 입력을 데이터베이스에서 사용할 수 있는 데이터베이스 입력 모델로 매핑한 후 데이터베이스 쿼리를 날립니다. 그리고 쿼리 결과를 도메인 엔티티로 매핑하여 유스 케이스로 반환합니다.

핵심은 영속성 어댑터의 입력 모델이 영속성 어댑터 내부에 있는 것이 아니라 애플리케이션 코어에 있기 때문에 영속성 어댑터 내부를 변경하는 것이 코어에 영향을 미치지 않는다는 것입니다.

유지보수 가능한 영속성 어댑터를 만들려면 어떻게 해야할까?

영속성 계층에서 모든 데이터베이스 연산을 하나의 리포지토리에 넣으면 유스 케이스 서비스에서 살펴봤던 넓은 서비스 문제와 비슷한 넓은 포트 인터페이스 문제가 발생할 수 있습니다. 넓은 포트 인터페이스는 특정 엔티티가 필요로 하는 모든 데이터베이스 연산을 하나의 리포지토리 인터페이스에 넣어둔 것을 말합니다. 필요하지 않은 메서드에 대한 의존성은 코드를 이해하고 테스트하기 어렵게 만듭니다.

따라서 인터페이스 분리 원칙에 따라 좁은 포트를 만들어서 플러그 앤드 플레이가 가능하도록 해야 합니다. 이 원칙에 따르면 클라이언트가 오로지 자신이 필요로 하는 메서드만 알면 되도록 넓은 인터페이스를 특화된 인터페이스로 분리해야 합니다. 그러면 각 서비스는 필요한 메서드에만 의존하게 되므로 포트의 이름만 보고도 어떤 역할을 하는지 명확히 파악할 수 있습니다. 또한 테스트를 할 때도 어떤 메서드를 모킹해야 하는지 고민할 필요도 없습니다. 이렇게 좁은 포트를 만드는 것은 플러그 앤드 플레이 경험으로 이어집니다.

그러면 영속성 어댑터를 어떻게 나누어야 할까요? 영속성 연산이 필요한 도메인 클래스 하나당 영속성 어댑터 하나를 구현하는 방식을 선택할 수 있습니다. 그러면 영속성 어댑터들이 각 영속성 기능을 이용하는 도메인 경계를 따라 자동으로 나눠집니다.