로버트 C. 마틴의 저서인 클린 코드 8장 경계와 클린 아키텍처의 17장 경계: 선긋기에서는 코드와 코드 사이의 경계를 나누는 것의 중요성에 대해서 다루고 있습니다. 인상 깊었던 내용으로는 외부 API와 우리 코드 사이에 선을 긋고 인터페이스와 협력하며 코드를 우리 통제 하에 둬라, 아직 존재하지 않는 코드를 사용하기 위해 경계를 파악하라가 있습니다.
이번 애니프렌즈 프로젝트를 진행하며 아직 존재하지 않는 객체와 협력해야 하는 상황이 있었습니다. 마치 책에서 설명하던 것과 유사하였습니다. 그리고 해당 문제를 해결하기 위한 방법을 생각하며 책에서 설명한 내용에 대해서 약간은 더 이해할 수 있는 기회였기에 이에 대해서 정리하고자 합니다.
구현되지 않은 기능 사용하기
저희 팀은 이번 프로젝트를 기획하면서 이미지의 관리는 AWS S3를 이용하기로 결정을 하였습니다. 이러한 결정에 따라 S3를 이용한 이미지 업로드, 삭제는 2차 스프린트에 포함되어 있었습니다. 그리고 이미지 삭제 기능을 사용하는 봉사 모집글 수정, 사용자 프로필 이미지 수정 등의 로직을 구현하는 것 또한 2차 스프린트에 포함되었습니다.
이미지 수정이 이루어지는 경우 기존의 이미지를 삭제해야 했기에 S3에서 이미지 삭제를 담당하는 객체와 협력하도록 로직을 구현해야 했습니다. 그러나 이를 담당할 클래스는 아직까지 구현되지 않은 상태였습니다. 그렇다고 한들 이미지 삭제 기능을 먼저 구현하거나 S3Service
를 만들고 아무런 동작도 하지 않는 메서드를 만들 수는 없는 노릇입니다.
존재하지 않는 객체와 협력하기
S3를 이용한 이미지 삭제를 구현하기 전까지 다른 기능을 구현하지 않고 기다리는 것은 논센스입니다. 다만 이미지 삭제를 담당할 객체가 어떤 행위를 하는지, 행위를 위해 필요한 것이 무엇인지는 확실합니다.
- 이미지를 삭제한다는 행위를 수행한다.
- 행위를 수행하기 위해서는 이미지가 저장된 위치가 필요하다.
머지않아 만들어질 S3Service
는 이미지를 삭제하라는 메시지를 이해할 수 있을 것입니다. 따라서 ImageRemover
라는 인터페이스를 만들고 deleteImages(imageUrls)
라는 추상 메서드를 정의해주었습니다.
또한 빌드를 위해 S3를 이용한 구현이 완료되기 전까지 런타임에 다른 서비스들과 협력하기 위한 객체가 필요했습니다. 아직까지 실제로 이미지가 저장되고 삭제되는 구체적인 행위는 필요 없었기 때문에 가짜로 협력하기 위한 MockImageRemover
를 추가하였습니다.
이렇게 함으로써 실제 작동하는 기능이 구현되었는지와 상관없이 자유롭게 다른 기능들을 구현하고 테스트할 수 있게 되었습니다. 실행 또한 문제없이 이루어질 것입니다.
실제로 S3와 통신하는 이미지 삭제의 구현은 2차 스프린트가 시작하고 6일째 되는 날에 개발이 완료되었습니다. 반면 봉사 모집글 수정, 봉사자 프로필 이미지 수정과 같은 다양한 기능들은 ImageRemover
인터페이스를 사용하여 그보다 훨씬 더 빨리 개발할 수 있었습니다.
S3Service
의 구현까지 완료된 후 객체 사이의 관계는 다음과 같습니다.
그리고 위 그림을 보면 자연스럽게 다음 두 가지 원칙 역시 지켜지고 있음을 알 수 있습니다.
- 인터페이스 분리 원칙
- 의존성 역전 원칙
인터페이스 분리 원칙
도메인 패키지 아래에 있는 서비스들을 이미지 업로드에 대해서 알 필요가 없습니다. 이미지 업로드는 항상 별도의 API를 통해서 이루어지고 이미지 엔티티의 생성은 이미지가 저장된 URL만 입력받아 이루어집니다. 오직 이미지 삭제 시에만 도메인에서 통신이 이루어지기 때문에 ImageRemover
객체가 deleteImages()
라는 메시지를 이해할 수 있다라는 사실만 알고 있으면 충분합니다.
의존성 역전 원칙
도메인 패키지 아래에 있는 서비스들이 외부 API와 통신하는 S3Service
에 직접 의존하는 대신 오직 ImageRemover
인터페이스에만 의존함으로써 도메인 패키지와 글로벌 패키지간의 의존 관계를 역전 시킬 수 있습니다. 서비스 객체들은 이미지를 삭제한다는 핵심적인 사항만 알고 있으면 됩니다. 어디서 이미지를 삭제할지는 중요하지 않습니다.
S3에서 이미지를 삭제한다는 구체적인 사항은 분리함으로써 이미지를 관리하는 방법이 바뀌더라도 핵심 로직은 전혀 변경할 필요가 없을 것입니다.
'백엔드' 카테고리의 다른 글
낙관적 락, 데드락, 비관적 락 (1) | 2023.12.10 |
---|---|
로그 세팅하기 2탄. 프롬테일, 로키, 그라파나 (1) | 2023.12.02 |
AWS CodeDeploy를 이용한 배포 성공 이후 발생하는 permission denied (0) | 2023.11.07 |
Parameter와 Argument (0) | 2023.06.20 |
[디자인 패턴] 옵저버 패턴 (0) | 2023.06.19 |