프로그래밍백엔드 개발자

파이썬에서 객체 지향 프로그래밍의 조합(composition)과 집합(aggregation)이란 무엇이며, 이들은 어떻게 다르며 어디에 사용되는가?

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 배경:

조합과 집합이라는 두 용어는 전통적인 객체 지향 설계에서 비롯되었습니다. 이들은 객체 간의 관계를 설명합니다: "전체-부분"의 관계지만, 객체의 연결 강도에 따라 다릅니다.

문제:

큰 시스템에서 코드의 가독성과 확장성이 중요합니다. 조합과 집합은 클래스 간의 올바른 의존성을 설계하는 데 도움이 됩니다. 차이를 이해하는 것이 중요합니다 — 그렇지 않으면 아키텍처가 너무 경직되거나 모호해질 수 있습니다.

해결책:

조합 — 이는 "부분-전체" 간의 강한 연결입니다. 객체가 다른 객체 내에만 존재하고 그 외부에서는 존재할 수 없는 경우를 말합니다. Python에서 이러한 객체는 일반적으로 "컨테이너" 클래스 내에서 생성되고 관리됩니다.

집합 — 이는 더 약한 연결입니다. "부분" 객체는 "전체" 객체와 별도로 존재할 수 있으며 외부에서 전달될 수 있습니다.

코드 예시:

class Engine: def start(self): print("엔진 시작됨") class Car: # 조합: Car 내에 Engine 생성 def __init__(self): self.engine = Engine() def drive(self): self.engine.start() my_car = Car() my_car.drive() class Wheel: pass class Bicycle: # 집합: 바퀴를 외부에서 전달받음 def __init__(self, wheels): self.wheels = wheels w1, w2 = Wheel(), Wheel() bike = Bicycle([w1, w2])

주요 특징:

  • 조합은 포함된 객체의 생명 주기를 완전히 제어합니다.
  • 집합은 더 유연한 아키텍처와 약한 연결을 제공합니다.
  • 조합을 통해 "has-a" 패턴을 쉽게 구현할 수 있고, 집합을 통해 객체의 공유를 수행할 수 있습니다.

함정 질문.

객체 "컨테이너" (예: Car)를 삭제하면 객체 Engine도 삭제되나요?

조합의 경우, "부분" 객체를 참조하는 것이 더 이상 없다면, 가비지 컬렉터에 의해 삭제됩니다. 반면, 집합에서는 "부분" 객체가 계속 존재할 수 있습니다 (다른 객체들이 여전히 참조할 수 있습니다).

Python에는 다른 언어처럼 조합과 집합을 나타내는 특별한 구문이 있나요?

Python에는 조합/집합을 명시적으로 나타내는 키워드가 없습니다. 이는 객체의 생성 방식 및 생명 주기에 따라 다릅니다.

조합을 집합으로, 또는 그 반대로 로직을 재작성하지 않고 변경할 수 있나요?

항상 가능하지는 않습니다. 로직이 "부분" 객체에 대한 완전한 제어 및 고유성을 요구하는 경우, 조합을 집합으로 간단히 변경하면 오류가 발생할 수 있습니다 (예: 여러 자전거가 같은 클래스의 바퀴를 공유하게 될 경우).

일반적인 오류 및 안티 패턴

장점:

  • 조합은 객체의 구성 및 파괴에 대한 명확한 제어를 제공합니다.
  • 집합은 객체의 유연성과 재사용성을 제공합니다. 단점:
  • 조합은 지나치게 긴밀한 관계를 초래할 수 있습니다.
  • 집합은 때때로 객체의 "소유권 분리"로 인해 논리적 오류를 허용할 수 있습니다.

실제 사례

부정적인 사례: 프로젝트에서 각 자동차에 대해 외부 엔진 객체가 생성되어 집합을 통해 자동차에 전달되었습니다. 그러나 나중에 객체의 참조가 혼동되어 엔진이 자동차 간에 임의로 변경되어 혼란과 버그를 초래했습니다.

장점: 아키텍처는 유연해 보였습니다. 단점: 어떤 엔진이 어떤 자동차에 속하는지 이해하기 어려웠습니다.

긍정적인 사례: 다른 프로젝트에서는 엔진이 Car 클래스 내에서 생성되었습니다(조합); 자동차는 엔진을 직접 관리하여 신뢰성을 확보했습니다.

장점: 누수와 논리적 혼란이 없었습니다. 단점: 각 자동차와 그 세부 요소의 생명 주기를 관리하기 위해 조금 더 많은 코드를 작성해야 했습니다.