인프런 커뮤니티 질문&답변
의존 방향에 대한 고민
해결된 질문
작성
·
43
1
안녕하세요. 최근 객체 간 의존 방향 고민에 많은 시간을 쏟고 있어 질문드립니다.
핵심 질문
도메인/서비스 간 의존 방향을 결정할 때 어떤 기준을 적용하면 좋을까요?
"누가 누구를 알아야 하는가"에 대한 판단 기준이나 원칙이 있을까요?
저는 덜 중요한 개념의 변경이 중요한 개념에 영향을 주면 안된다고 생각하고 있었습니다. 그래서 중요한 개념이 덜 중요한 개념을 모르도록 코드를 짜려고 노력하는데요. 막상 개발할 때는 이게 잘 안되어서 고민에 시간을 많이 사용하거나, 타협하곤 합니다. 이런 상황이 이번 강의를 보면서도 나타나 질문글을 작성하게 되었습니다.
구체적인 상황
그런데 강의에서 download 메서드를 CouponService로 이동하는 과정을 보고 다음과 같은 의문이 들었습니다:
변경 후 구조:
CouponService → OwnedCoupon, OwnedCouponRepository 의존
OwnedCoupon → Coupon, CouponRepository 의존
우려 사항:
Coupon과 OwnedCoupon이 서로를 알게 되는 것이 순환 참조나 강결합을 유발하지 않을까?
OwnedCoupon에 필드 추가 시, 기존에는 OwnedCouponService만 수정하면 됐지만 이제는 CouponService도 함께 수정해야 함
논리적으로는 CouponService에 download 기능이 있는 것이 맞아 보이지만, Coupon과 OwnedCoupon이 서로 알게 되는 것이 괜찮은 설계인가?
이런 고민에 시간을 많이 쓰다 보니 개발 시간이 부족하다고 느껴집니다. 마감을 위해 구현 후 리팩토링하는 방식으로 진행하고 있지만, 리팩토링을 못할 때도 많고 마음의 짐으로 남는 것 같습니다.
조언 부탁드립니다. 감사합니다.
답변 2
1
안녕하세요 질문 감사드립니다!
아주 멋진 고민들을 하고 계시군요! 그 과정 자체가 좋은 훈련이라고 생각합니다
우선 적어주신 상황에 대해 종합적인 제 의견을 드리겠습니다
Coupon과 OwnedCoupon은 개념적으로 같은 격벽안에 존재합니다
정확히 보면 Coupon을 기반으로 OwnedCoupon이 만들어지는 구조를 갖고 있습니다
(다만 이걸 부모 자식의 관계라 보기는 어렵다고 생각합니다)
같은 격벽에 존재하는 측면에서는 서로 알고 있는 부분이 크게 문제가 되지 않을 것 같습니다
물론 이 부분이 맘에 너무 걸린다하면 ownedCoupon 에 coupon 정보를 모두 다 넣어 버리면 ownedCoupon은 coupon을 몰라도 되겠지만 이러면 데이터 구조 및 요구사항을 불만족 하는 부분이 생기게 되겠죠, 다른 관점의 타협하는 측면에선 다른 형태의 쿠폰 데이터 객체(ex]CouponCondition..)를 구성 할 수도 있을 것 같습니다
적어주신 수정 관점에서 말해주신 부분은 아주 타당한 관점입니다 그 측면으로 보면 OwnedCouponService에 있는게 맞죠 😃
결국 어떤 시선으로 내가 보고 개념의 구조를 잡아갈 것인가? 이게 중요합니다
Coupon 과 OwnedCoupon은 같은 개념 군집(격벽 안에) 있는가?
Coupon 과 OwnedCoupon의 거리는 얼마나 떨어져있는가?
Coupon 과 OwnedCoupon의 응집도가 서로를 알고 있는게 해가 되는가?
요구사항 기준 OwnedCoupon이 Coupon을 모를 수 있는가?
사용자가 쿠폰을 다운로드 한다 의 의미를 OwnedCoupon를 기준점으로 바라봐도 괜찮은가?
이런 느낌의 질문들을 해보시고 어떻게 구성할지 기준을 정하시면 됩니다 😃
(이미 적어주신 우려 사항들도 충분히 좋은 관점들입니다)
사실 적어주신 것 처럼 논리적으로 동작 흐름을 이해해보면 정적인 Coupon을 다운로드 하면 동적인(소유 관점) OwnedCoupon이 생성이 되는게 맞기 때문에 CouponService가 타당해 보이긴합니다만
이걸 쉽게 뒤집어 보면 말장난과 같습니다
OwnedCoupon은 정적 기준 데이터인 Coupon을 통해서 생성 될 수 있다
그러므로 interface 역할을 하는 CouponId 를 전달 받아서 스스로를 생성한다.이것을
쿠폰 다운로드라고 보지 않고 소유 쿠폰 생성 관점으로 보겠다
라고 한다면 말이 이상하지 않습니다ㅎㅎ;;
그래서 이 강의의 목적도 그랬지만 최대한 많은 고민을 하시면서 기준을 정해보시길 바랍니다 😃
결국은 우리가 선택한 것이 기준이 되기 때문에 나와 팀원이 충분히 납득 할 수 있는 방향이라면 그것이 정답에 가까운 것이라고 생각합니다
또한 코드는 지속적으로 계속 가꿔가야한다 생각합니다! 그래서 너무 깊은 고민보다는 요구사항 구현을 먼저 충족 하면서 고민을 계속하고 구현 완료 후 남는 시간에 한번 더 리뷰를 해서 정리하거나, 추후 리펙토링 대상으로 가져가야 한다고 봅니다
(다만 추후 리펙토링 이 말은 현실적으로 안/못 보겠다는 것이랑 비슷해서.... 일정이 빠듯하면 어려운 문제입니다)
모쪼록 답이 되었길 바랍니다! 감사합니다!
0
안녕하세요, 인프런 AI 인턴입니다. 자두님.
도메인/서비스 간의 의존 방향에 대해 깊이 있는 고민을 하고 계시는군요. 코드 설계와 아키텍처에서 의존 관계의 방향은 매우 중요한 요소입니다. 그것이 어떻게 설정되냐에 따라 시스템의 유지보수성, 확장성, 그리고 클린 아키텍처 구현에 큰 영향을 미칠 수 있습니다.
의존성 관리에 대한 기본 원칙
단일 책임 원칙(SRP): 각 클래스나 모듈이 단 하나의 책임만 다루도록 설계하세요. 이는 어떤 클래스가 변경되어야 할 때 그 이유가 하나여야 한다는 것을 의미합니다.
의존성 역전 원칙(DIP): 고수준 모듈이 저수준 모듈의 구현 세부사항에 의존하지 않도록 하고, 대신 추상화된 인터페이스에 의존하게 만드세요.
개방-폐쇄 원칙(OCP): 코드 구조를 기능 추가에는 열려 있지만, 수정에는 닫혀 있도록 유지하세요. 이는 새로운 기능을 기존 코드를 수정하지 않고 추가할 수 있게 만드는 것을 목표로 합니다.
구체적인 상황과 해결책
Coupon과 OwnedCoupon 간의 관계:
- 만약 두 클래스가 서로를 알아야 하는 강결합 관계라면, 인터페이스나 추상 클래스를 사용해 의존성을 주입하고, 이들이 직접적으로 서로에 의존하지 않도록 할 수 있습니다. 이를 통해 결합도를 낮추고, 더 유연한 구조로 개선할 수 있습니다.
- 만약 두 클래스가 서로를 알아야 하는 강결합 관계라면, 인터페이스나 추상 클래스를 사용해 의존성을 주입하고, 이들이 직접적으로 서로에 의존하지 않도록 할 수 있습니다. 이를 통해 결합도를 낮추고, 더 유연한 구조로 개선할 수 있습니다.
순환 참조 문제:
- 순환 참조는 시스템을 무너뜨릴 수 있는 포인트가 될 수 있습니다. 이를 피하기 위해 중재자 패턴(Mediator Pattern)이나 이벤트 버스 등을 사용하여 서로 간의 직접적인 참조를 피할 수 있습니다.
- 순환 참조는 시스템을 무너뜨릴 수 있는 포인트가 될 수 있습니다. 이를 피하기 위해 중재자 패턴(Mediator Pattern)이나 이벤트 버스 등을 사용하여 서로 간의 직접적인 참조를 피할 수 있습니다.
필드 추가에 의한 파급효과:
- 이는 데이터의 변경이 최소한의 파급 효과를 가져오도록 설계를 유연하게 만드는 것이 필요합니다. 이를 위해 데이터 변화의 영향 범위를 좁게 하는 로직 구성을 고민해보세요.
- 이는 데이터의 변경이 최소한의 파급 효과를 가져오도록 설계를 유연하게 만드는 것이 필요합니다. 이를 위해 데이터 변화의 영향 범위를 좁게 하는 로직 구성을 고민해보세요.
리팩토링 전략
리팩토링을 계획하고 시간을 확보하는 것도 중요합니다. 일단 구현하고 나서, 주기적으로 기술 부채를 갚아야 함을 염두에 두고 일정을 잡는 것도 좋은 방법입니다.
끝으로
각각의 상황이 다르고, 모든 결정에는 트레이드 오프가 존재합니다. 컨텍스트에 따라 최적의 결정을 할 수 있는 감각을 기르는 것이 중요하며, 그것은 경험과 학습을 통해 개발할 수 있습니다.
관련된 학습 자료로 아래 링크를 참고하면 도움이 될 것입니다:
- Service 간 의존하는 경우: 이 질문에서는 서로 다른 서비스 간의 의존성을 피하고 건강한 결합도를 유지하는 방법에 대해 다루고 있습니다.
자두님의 이해를 돕고자 제가 참고할 만한 기존 자료를 함께 안내드렸습니다. 베타 기능으로 이 답변이 충분히 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.





답변을 받고 어제부터 오늘까지 객체 간의 의존 방향을 정할 때 활용할 수 있는 질문들을 미리 정리해두고 코딩을 했는데, 이전보다 고민하는 시간이 단축되었습니다.
남은 강의도 여러 고민을 하면서 수강하도록 하겠습니다. 답변 감사합니다.