객체지향프로그래밍(16) - 집합(aggregation)과 합성(composition)

오버라이딩의 정의와 활용

Featured image

🔚 짧게 하는 복습

✅ 1. 다중 상속의 정의와 사용법을 안다.

✅ 2. 다중 상속의 특징 중 하나인 다이아몬드 문제를 안다.

✅ 3. 다중 상속을 쓰기 어려운 이유를 안다.

혹시 기억이 안 난다면, 다시 돌아가자


저번 강의까지는 상속을 이용한 구조에 대해서 다루었다.

is-a, has-a, 계층 구조, 다중 상속까지 상속을 이용해서 많은 구조를 나타낼 수 있었다.

오늘 다루고자 하는 것은 has-a 관계, 과연 상속만이 답일까? 다른 구조는 없을까? 라는 질문에서 시작한다.

저번 14강의 더 읽어보기를 미리 공부했더라면 상속이 아니라 합성(Composition)이라는 구조로 나타낼 수 있다고 했다.

사실 has-a 관계를 나타내는 것은 합성말고도 집합(Aggregation)이라는 구조도 있다.

오늘은 이 두 관계, 집합합성에 대해서 알아보겠다.


집합(Aggregation)이란?

학교와 학생은 어떤 관계인가? is-a? has-a?

당연히 has-a 관계이다. 학생은 학교가 아니고, 학교도 학생이 아니며 학교가 학생을 가지기 때문이다.

그런데 학생이 학교를 벗어나면 사라지거나, 독립적으로 존재할 수 없는가? 그것 역시 아니다.

이렇게 한 객체가 다른 객체를 포함할 때, 포함되는 객체가 독립적으로 존재할 수 있다면 그것은 집합 관계(Aggregation)이라고 한다.

위의 예제 코드를 보면, 학교가 동적할당 배열을 통해 학생들을 관리하고 있다.

학생들을 추가할 수 있고 정보를 표시하는 기능도 있다.

그런데 학교라는 객체가 사라지더라도, 학생이라는 객체들은 모두 그대로다.


집합 관계의 특징

집합 관계는 객체 간의 약한 연결을 제공하므로 객체를 다른 용도로 재사용하거나 변경하기 쉽다.

또, 객체 사이의 독립성을 유지하므로 각 객체를 개별적으로 수정하거나 확장하기 용이하다.

마지막으로, 객체 간의 관계가 명확하고 간단하게 정의되므로 코드의 가독성을 높일 수 있다.

하지만 단점으로는 부모 객체와 자식 객체 간의 생명주기가 분리되어 있어 메모리 관리와 수명 관리에 주의해야 한다.

Class Diagram에서는 아래와 같이 속이 빈 마름모를 가진 화살표로 연결한다.


합성(Composition)

다음은 더 강한 연결(Stronger Aggregation)의 성질을 가진 합성(Composition)이라는 관계이다.

합성하나의 클래스가 어떤 클래스를 포함할 때, 포함한 클래스와 포함된 클래스가 같은 수명을 가지는 것을 의미한다.

집과 방들의 관계가 있다. 예를 들어 화장실, 거실, 안방이 있다고 하자.

만약 집이 철거되면, 방들이 그 자체로 존재할 수 있는가? 일반적일 때 아니다.

이렇게 포함한 객체가 사라질 때, 포함된 객체들도 같이 소멸되면 이 관계를 합성 관계라고 한다.

아래의 코드를 보자.

대충 보면 Aggregation 관계와 뭐가 다른가 싶지만, 여기는 집이 사라질 때 방도 같이 사라진다.

합성과 집합 관계의 가장 큰 차이는 소멸자이다.

집합 관계는 포함한 객체 하나만 소멸하지만, 합성 관계는 포함한 객체가 사라질 때 포함된 객체들도 같이 사라진다.

전자보다 유연하지 않아서 단점만 있을 것 같지만, 아래와 같은 특징이 있다.


합성 관계의 특징

합성 관계는 객체들 사이의 강한 연결을 제공하므로 한 객체의 일부가 다른 객체에 의존할 때 객체의 일관성을 유지하기 좋다.

객체 간의 관계가 밀접하게 연결되어 있다. 그렇기에 캡슐화를 강화하고 시스템의 복잡성을 줄일 수 있습니다.

포함한 객체와 포함된 객체가 함께 소멸하므로 메모리 관리가 용이하다.

반면에 코드 작성의 유연성이 감소하고, 강한 연결로 의해 의존성이 발생하여 유지보수가 어려워질 수 있다는 단점도 있다.

Class Diagram에서는 아래와 같이 속이 가득 찬 마름모 화살표로 나타난다.


주의 사항

지금까지 클래스의 관계를 나타내는 여러 방법을 배웠다.

그런데 여기서 중요한 점은 어느 방법이 좋다 혹은 안 좋다라는 이분법을 사용하면 안 된다.

어떠한 상황에서는 이 관계가 필요할 수 있고, 다른 상황에서는 또 이런 관계가 아니면 안 될 수 있다.

그렇기에 하나의 방법으로 모든 상황을 대처할 수도 없고, 여러 방법에 익숙해져서 상황에 맞게 사용하는 것이 가장 중요하다.

또한, 많은 강의에서 is-a는 상속으로 has-a는 합성으로 표현하라고 한다.

이 역시, 단순한 공식처럼 외우기보다는 왜 그런지 원리를 이해해서, 유연하게 사용할 수 있으면 더 좋을 듯하다.


📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. 집합 관계의 정의와 특징을 안다.

✅ 2. 합성 관계의 정의와 특징을 안다.

✅ 3. 지금까지 배운 클래스간 구조의 장단점들을 안다.

⚠️ 클래스간의 구조에는 우열이 없다.

💣 과제, 왜 상속은 is-a를 많이 쓰고, 합성은 has-a를 많이 쓸지 생각해보자(난이도 中)