본문 바로가기
Concepts/UML

UML - 클래스 다이어그램 고급 - 집합과 합성

by ocwokocw 2021. 2. 10.

- 이 글은 UML Distilled (마틴 파울러)책을 기반으로 작성하였습니다.

https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-aggregation-vs-composition/

- 집합(Aggregation)과 합성(Composition)

집합과 합성은 UML 에서 가장 헷갈리는 개념이다. 여기에다가 연관까지 끼어서 연관과 집합과 합성은 무엇이냐라고 묻는다면 이 질문이 곧 지옥이다.

 

집합을 단순하게 정의하기는 쉽다. 일부분이 되는 관계이며, 자동차가 엔진과 바퀴를 갖고 있는것과 같다고 정의하기도 한다. 하지만 이런 정의는 너무도 애매해서 집합의 개념을 모델링을 하는 사람마다 다르게 사용한다. 

 

이런 애매한 정의로는 집합과 합성을 구분할 수 없다. 집합과 합성을 구분할 때에는 전체와 부분의 관계를 우선 생각하고, 전체가 삭제될 때 부분도 삭제가 되느냐를 생각해보는것이 유용하다. 


- 합성(Composition)

만약 둘 사이의 강력한 의존관계가 있어서 하나가 삭제 되었을 때 다른 하나가 존재할 수 없다면, 이는 합성(Composition)관계이다. 합성은 포함관계로 설명되기도 한다. 방은 집에 포함되어있다(belongs-to)고 얘기할 수도 있고, 집은 방을 가지고 있다(has-a)고 얘기할 수도 있다.

위 다이어그램에서 Person 쪽에 속이 채워진 마름모가 있는것이 보일 것이다. 이 기호가 합성(Composition)기호이다. 마름모의 방향이 헷갈린다면 더 범위가 큰 쪽에 마름모를 표시한다고 생각하면 될 것이다. 위의 그림에서 모델러는 Person이 삭제된다면 Head, Body, Leg 도 존재하지 않는다고 가정하였다.

 

이걸 Java 코드에서는 어떻게 표현할까? Composition과 같이 has-a 관계는 private 변수를 사용하여 나타낸다. 사람이 태어나면서 머리와 몸통과 다리가 생겨난다. 일정기간이 지남에 따라 자라고 길이도 알 수 있다. 사람이 죽으면 각 신체기관도 소멸된다. head, body, legs에 null 을 할당하여 가비지 컬렉션 대상이 됨을 명시할수도 있지만 소멸은 표현하지 않았다. 

 

public class Person {

	private Head head;
	private Body body;
	private List<Leg> legs;
	
	public Person() {
		super();
		this.head = new Head();
		this.body = new Body();
		this.legs = Arrays.asList(new Leg(), new Leg());
	}

	public void growUp() {
		
		head.growUp(1);
		body.growUp(2);
		legs.stream()
			.forEach(leg -> leg.growUp(5));
	}
	
	public void checkLengths() {
		
		System.out.println(head);
		System.out.println(body);
		legs.stream()
			.forEach(System.out::println);
	}
}

- 집합(Aggregation)

집합(Aggregation) 관계는 A 클래스가 B를 소유하고 있다거나, A 클래스가 B의 부모라거나 하는 것을 가리키는것이 아니다. A 클래스의 인스턴스는 B 클래스의 인스턴스와 배타적이지(독립적이지) 않다는것을 강조하기 위한것이다.

위 다이어그램에서 Engine과 Wheel은 Car와 집합관계이지만 차가 없어진다고 해서 Engine과 Wheel이 삭제된다고 보진 않았다. 물론 이 설계는 프로그램 설계 특성에 따라 변경될 수는 있을 것이다.

 

Aggregation은 아래처럼 참조만 하면 된다. 다른 바퀴나 엔진으로 교체될 수 있으며 생명주기가 동기화될 필요는 없다.

 

public class Car {

	Engine engine;
	List<Wheel> wheels;
}

- 연관과의 관계

집합과 합성이 연관과 어떻게 관련이 있는가? 

 

연관이란 다른 클래스에서 제공하는 기능을 사용하는것을 나타내는 일반적인 용어라고 할 수 있다. 때문에 집합과 합성은 연관의 특수한 부분집합이라고 할 수 있다. 또한 소스코드상으로 연관은 집합(Aggregation)과 구분할 수 없다.

댓글