본 게시물은 도서 [UML 실전에서는 이것만 쓴다]의 내용을 재구성 하여 작성하였습니다. 본 게시물이 출판사/작가의 저작권의 침해할 소지가 있는 경우 비공개/삭제 될 수 있음을 알립니다.
클래스 스테레오타입
클레스 스테레오타입은 보통 클래스의 이름 위에 놓인 길러맷(guillemet) 사이에 적는데, 아마 본 적이 있을 것이다. 아래의 그림의 <<interface>> 표기가 바로 클래스 스테레오타입이다.
자바 프로그래머가 사용할 만한 두 가지 스테레오타입은 <<interface>>와 <<utility>>다
<<interface>> 이 스테레오 타입이 붙은 클래스의 메서드는 모두 추상 메서드이므로, 어떤 메서드도 구현해서는 안된다. 그리고 <<interface>> 클래스는 인스턴스 변수를 가지지 못한다. 오직 정적(static) 변수만 가질 수 있다. 이것은 자바의 인터페이스에 정확히 대응된다.
<<utility>> <<utility>> 클래스의 모든 메서드와 변수 들은 정적(static)이다.
자신만의 스테레오 타입을 만들고 싶다면 그렇게 해도 된다. 오직 여러분의 다이어그램을 읽을 사람이 그것의 의미를 알기만 하면 된다.
추상 클래스
UML에서 추상 클래스나 추상 메서드를 표기하는 방법은 두 가지다. 이름을 이탤릭체로 적거나, {abstract} 프로퍼티를 사용하는 것이다. 두 경우 모두 아래 그림에 나온다.
이탤릭체로 적기가 어렵고 {abstract} 프로퍼티를 사용하는 것도 단어가 긴 경우 추상을 표기하려면 아래의 그림처럼 약어를 사용한다.
프로퍼티
{abstract} 프로퍼티는 어떤 클래스에도 붙일 수 있다. 프로퍼티는 보통 클래스에 속하지 않는 추가 정보를 나타낸다. 프로퍼티는 다음처럼 쉼표(,)로 분리된 이름-값 쌍으로 적는다.
{author=Martin, date=20161230, file=shape.java, private}
위 예제의 프로퍼티들은 UML에 들어있는 것이 아니다. {abstract} 프로퍼티는 UML에서 미리 정의한 것 가운데 거의 유일하게 자바 프로그래머에게 유용할 만한 프로퍼티다. 만약 프로퍼티가 값을 가지지 않는다면, 불린 값 참(true)을 가지는 것으로 간주한다. 따라서 {abstract}와 {abstract = true}는 같은 뜻이다.
프로퍼티는 아래 그림처럼 클래스 이름의 오른쪽 아래에 적는다.
집합
집합(aggregation)은 '부분/전체' 관계를 내포하는 연관의 특별한 형태다. 아래의 그림에서 집합을 그리는 방법과 구현 방법을 보여준다. 아래의 그림에서 구현이 연관과 차이가 없다는 점을 눈여겨 보아라. 이것이 힌트다.
사실 UML은 명확한 집합의 정의를 제공하지 않는다. 그래서 여러 프로그래머와 분석가가 집합 관계에 대해 자기 나름의 정의를 내렸기 때문에 혼란이 생겼다. 이런 이유로 나는 집합 관계를 전혀 사용하지 않으며, 여러분도 피했으면 좋겠다. 사실 집합 관계는 UML2.0에서 빠져버렸다.
UML이 집합에 유일하게 제공하는 명확한 규칙은 다음 몇가지 뿐이다. 전체는 자신의 부분이 될 수 없다. 따라서 '인스턴스들'이 집합을 통한 순환 고리를 만들 수는 없다. 어떤 객체가 자기 자신의 부분이 될 수 없고, 두 객체가 서로 상대 객체의 부분이 될 수도 없고, 세 객체가 전부/부분 관계의 고리를 만들 수도 없다 등등...
합성
합성(composition)은 다음 페이지에서 보다시피 집합의 특별한 형태다. 다시 한 번 합성의 구현도 연관의 구현과 구분하지 못한다는 것을 눈여겨 보아라. 하지만, 이번에는 집합처럼 뚜렷한 정의가 없어서 그런 것이 아니다. 자바 프로그램에서는 이 관계가 그다지 유용하지 않기 때문이다. 반면 C++ 프로그래머에게는 합성 관계가 '매우' 유용하다.
집합과 똑같은 규칙이 합성에서도 적용된다. 인스턴스의 순환 고리를 만들지 못한다. 주인(Owner)이 자신의 피보호자(Ward)가 될 수는 없다 등등. 하지만, UML에서 합성에 대한 정의에는 집합과 공통된 규칙 말고도 많은 항목이 들어 있다.
- 피보호자의 한 인스턴스를 두 주인이 동시에 소유하지 못한다. 아래 그림의 객체 다이어그램은 잘못되었다. 하지만, 이 객체 다이어그램과 대응하는 클래스 다이어그램은 문제없다. 주인이 피보호자의 소유권을 다른 주인에게 이전하면 된다.
- 주인은 피보호자의 수명 전체에 책임을 진다. 만약 주인이 소멸되면, 피보호자도 함께 소멸되어야 한다. 주인이 복사되면, 피보호자도 복사되어야 한다.
자바에서 객체 소멸은 보이지 않는 곳에서 가비지 컬렉터가 수행하므로 어떤 객체의 수명을 관리할 필요는 거의 없다. 딥 카피는 흔히 사용되지만, 딥 카피를 해야 한다고 다이어그램에 표시하는 경우는 드물다.
아래의 그림은 딥 카피를 해야 한다는 것을 표기하기 위해 합성을 사용하는 방법을 보여준다. 여기에 여러 문자열(String)을 가진 주소(Address)라는 클래스가 있다. 이 클래스는 문자열마다 주소를 한 줄씩 담는다. 주소를 복사한 다음에 복사한 주소를 변경하는 경우, 원래 주소는 변경되지 말아야 하므로 반드시 딥 카피를 수행해야 한다. 주소와 문자열 사이의 합성 관계는 딥 카피를 해야 한다는 것을 나타낸다.