Composition
합성은 객체가 다른 객체들을 협력자로 가지고 있으면서 필요한 일을 그 객체들에게 위임해 전체 동작을 만드는 방식입니다. 재사용의 중심을 상속 계층이 아니라 협력 객체의 조합에 두는 설계라고 보면 됩니다.
▶아키텍처 다이어그램
🔍 구조 다이어그램점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다
재사용을 상속으로만 풀면 비슷한 기능을 얻기 위해 부모 클래스에 계속 매달리게 됩니다. 그 결과 계층은 깊어지고 부모의 작은 변경 하나가 멀리 있는 자식 클래스까지 영향을 줍니다. 기능은 재사용했지만 구조는 더 경직되는 상황이 자주 생깁니다.
실무 경험이 쌓이면서 상속 중심 설계가 생각보다 취약하다는 점이 반복해서 드러났습니다. GoF 패턴 이후 상속보다 합성을 우선하라는 조언이 널리 퍼진 것도, 큰 기능을 작은 협력 객체의 조합으로 푸는 편이 변경과 테스트에 더 유리한 경우가 많았기 때문입니다.
합성에서는 상위 객체가 역할별 협력 객체를 필드로 들고 있습니다. 요청이 들어오면 상위 객체가 전체 흐름을 조정하고, 검증은 검증기에게, 저장은 저장소에게, 정책 판단은 정책 객체에게 맡기는 식으로 세부 책임을 위임합니다. 이렇게 하면 외부에서는 하나의 기능처럼 보이지만 내부는 여러 객체의 협력으로 구성됩니다.
합성과 상속은 둘 다 재사용을 다루지만 결합 방식이 다릅니다. 상속은 부모 구현을 직접 물려받는 대신 부모 변화에 민감해지고, 합성은 필요한 역할의 객체를 주입해 협력시키므로 교체와 조합이 더 쉽습니다. 재사용이 목적이라면 어떤 방식이 더 느슨한 경계를 주는지 먼저 따져 봐야 합니다.
서비스 계층, 전략 객체, 정책 객체, UI 조합 구조처럼 역할을 나누고 필요에 따라 구현체를 바꿔 끼워야 하는 곳에서 합성이 특히 강합니다. 다만 객체를 지나치게 잘게 나누면 로직 하나를 이해하기 위해 따라가야 할 협력 관계가 너무 많아질 수 있습니다.