UML Diagram with Swift
UML Class Diagram
UML 클래스 다이어그램은 객체 지향 시스템을 구성하고 시각화하는데 사용되는 그래픽적 표현이다. UML은 Unified Modeling Language의 약어로, UML의 클래스 다이어그램은 구조적인 다이어그램으로 다음의 시스템 요소들을 표현한다.
- 클래스
- 클래스의 속성
- 연산(메서드)
- 객체간의 관계
이름에서부터 알 수 있듯이 객체 지향 시스템의 핵심이 되는 객체를 생성하기 위한 '클래스'와 그들의 능력, 객체간의 관계를 시각적으로 표현한다.
Class란
Class가 무엇인지 모르고 클래스 다이어그램을 그릴 수는 없다.
클래스는 객체를 찍어낼 수 있는 틀이 된다. 클래스와 객체는 서로를 빼놓고 얘기할 수 없다. 객체 지향 디자인의 핵심은 객체가 아닌 클래스에 관한 것인데, 이는 클래스를 사용해서 객체를 생성하기 때문이다. 그래서 클래스는 객체가 어떤 특징을 갖고 어떤 연산을 할 수 있는지를 정의하지만, 객체는 스스로를 정의하지 않는다.
UML Class 표기법
클래스는 상태(attribute)와 행위(operation)을 캡슐화하는 개념을 나타낸다. 클래스 다이어그램은 클래스 이름, 클래스의 상태, 클래스의 행위를 표현해야 한다.
- 클래스 이름
- 필수적인 정보
- 맨 위에 기입한다.
- Attribute
attributeName : type
- 타입이 있다. 타입은 콜론 다음에 표시한다.
- 두 번째 위치에 기입한다.
- 각각의 attribute는 코드 상에서 멤버 변수가 된다.
- Operation
operation(inputSignature) : outputSignature
- 클래스가 제공하는 서비스다.
- 세 번째 위치에 기입한다.
- 리턴 타입의 메서는 메서드 signature(input과 output을 정의하는 것)의 콜론 다음에 기입한다.
- 각각의 Operation은 코드 상에서 메서드가 된다.
Class Visibility (접근 레벨)
Attribute, operation 이름 전에 붙는 +
, -
, #
심볼은 각각의 attribute와 operation의 가시성(접근 레벨)을 표시한다.
+
: public-
: private#
: protected
Parameter Directionality
Operation(method)의 각각의 파라미터는 in
, out
, inout
으로 표시해서 호출하는 곳에 상대적인 방향을 나타낸다. 이런 방향은 파라미터 이름 전에 표시한다.
in
: 호출자에 의해 전달됨out
: 호출자에 의해 전달되지 않지만, 결과로 나옴inout
: 호출자에 의해 전달되고, 연산에 의해 수정될 수 있드며 결과로 나온다.
클래스 간의 관계
UML은 단순히 클래스를 표현하기 위한 수단에서 그치지 않고 올바르게 사용했을 때 코드가 어떻게 구현되어야 하는지를 묘사하는 수단이 될 수 있다. 올바르게 해석되었을 때 구현된 코드는 디자이너의 의도를 완벽하게 반영할 수 있을 것이다.
클래스는 다른 클래스와의 관계가 없을 수도 있고, 하나 이상의 관계를 맺고 있을 수도 있다. 관계는 다음의 종류가 있다.
- Association
- Inheritance / Generalization
- Realization
- Dependency
- Aggregation
- Composition
특히 Aggregation과 Composition은 집합 관계에 포함된다.
- Association
- Generalization
- 집합 관계
- Aggregation
- Composition
- Dependency
- Realization
1. Association - 연관 관계
연관 관계는 UML 클래스 다이어그램의 클래스 간의 관계다. 딱히 특별한 것은 없고 관계라고만 생각하면 된다. 관계를 맺으면 클래스는 해당 연관 관계에서 어떤 역할을 수행한다.
두 클래스가 있고 두 클래스가 연관 관계를 맺고 있을 때 실선을 그어 연관 관계를 표시한다.
예를 들어 선생님 클래스와 학생 클래스가 있을 때 선생님이 학생을 가르치는 연관 관계를 코드로 표현하면 아래와 같이 될 것이다.
class Teacher {
func teach(student: Student) {}
}
class Student {
}
연관 관계를 표시할 때 추가로 다른 정보들도 같이 표시할 수 있다.
연관 관계 이름
두 클래스 사이의 연관관계를 나타내기 위해 사용한다.
Cardinality (다중성)
- 일대일
- 일대다
- 다대다
선에 아무런 숫자가 없으면 일대일 관계다.
방향
연관 관계는 방향성을 가질 수 있다.
- 양방향 : 실선. 두 클래스의 객체가 서로를 알고 있다.
- 단방향 : 화살표. 한쪽은 다른 클래스를 알지만 다른 클래스는 상대방을 모른다
연관 클래스
- 연관 관계에 추가할 속성이나 행위가 있을 때 사용한다. 연관 클래스는 두 클래스 사이에 위치시키고 점선을 사용해서 연결한다.
- 연관 클래스를 일반 클래스로 바꿔 다대다에서 일대다 연관 관계로 변환할 수 있다.
위 그림의 "대본" 클래스는 연관 클래스로 존재하지만, 이를 일반 클래스로 변환함으로써 교수 : 대본, 강의 : 대본을 일대다 관계로 변환했다.
2. Inheritance / Generalization - 상속, 일반화 관계
한 클래스가 다른 클래스를 포함하는 상위 개념일 때 존재한다. 즉 일반적인 클래스가 있고, 더 구체적인 클래스가 있다.
구체적인 클래스의 인스턴들은 일반적인 클래스의 간접적인 인스턴스가 된다. 일반적인 클래스는 구체적인 클래스의 공통 속성이나 연산을 제공하게 되고, 따라서 구체적인 클래스는 일반적인 클래스의 특징을 상속받는다.
- "is-a" 관계를 표현한다.
- 추상 클래스 이름은 이태릭체로 표시한다.
가령 아래와 같이 Animal
이라는 일반적인 클래스가 있고 이를 상속하는 구체적인 Cat
클래스가 있다고 해보자. Cat
클래스는 Animal
클래스의 특성을 사용할 수 있고, 추가로 자신만의 더 구체적인 특성을 가지고 있을 수 있다.
class Animal {
var name: String = ""
func roar() {}
}
class Cat: Animal {
var favoriteFish: String = ""
}
클래스 다이어그램에서는 아래와 같이 빈 삼각형을 머리로 하는 화살표로 클래스간의 관계를 표시한다.
3. Realization - 실체화 관계
실체화 관계는 하나의 청사진과 이를 구현하는 객체가 맺는 관계다. 이 객체는 청사진 클래스를 실체화했다고 말한다. 즉 인터페이스와 구현 클래스 간의 관계라고 생각하면 된다.
가령 위와 같이 Owner
인터페이스가 있고, 얻고 해제하는 메서드를 명시하고 있다고 해보자. Person
과 Corportation
클래스는 이런 메서드를 각각 다른 방법으로 구현할 수 있다.
이를 코드로 나타내면 아래와 같다.
protocol Owner {
func acquire()
func dispose()
}
class Person: Owner {
func acquire() {
print("Person acquires")
}
func dispose() {
print("Person disposes")
}
}
class Corporation: Owner {
func acquire() {
print("Corporation acquires")
}
func dispose() {
print("Corporation disposes")
}
}
4. Dependency - 의존 관계
한 클래스가 메서드에서 다른 클래스의 객체를 사용할 수 있는 관계를 의미한다. 메서드에서 사용한다는 것은 메서드의 파라미터로 사용될 때, 메서드 내부에서 사용되는 경우가 있을 수 있다. 만약 객체가 어디에도 저장되어 있지 않다면 의존 관계로 모델링되기도 한다.
이런 관계에서는 한 클래스의 정의를 바꾸면 다른 것에 영향을 끼친다. 예를 들어 클래스 A가 클래스 B에 의존할 때 클래스 B가 변한다면 클래스 A에도 영향이 있을 것이다. 하지만 그 역은 그렇지 않다.
의존 관계는 점선 화살표로 표시한다.
코드로는 아래와 같이 나타낼 수 있다.
class Person {
func google(notebook: Notebook) {
// do sth with notebook
}
}
class Notebook {}
5. Aggregation - 집약 관계
한 객체가 다른 객체를 포함하는 관계를 나타낸다.
- "part of" 관계를 나타낸다.
- 한 객체가 다른 객체를 가지고 있기 때문에 일대다 관계를 가지고 있다.
- 각 클래스의 객체는 별개의 lifetime을 갖고 있다. 즉 다른 객체를 가진 객체가 메모리에서 없어져도 그 객체가 가지고 있던 객체는 사라지지 않는다.
- 다른 객체를 갖는 클래스 방향에 빈 마름모로 표시한다.
위 클래스 다이어그램을 코드로 표현하면 아래와 같이 될 것이다.
class Computer {
var gpu: GPU
init(gpu: GPU) {
self.gpu = gpu
}
deinit {
print("deinit computer")
}
}
class GPU {
deinit {
print("deinit gpu")
}
}
6. Composition - 합성 관계
한 객체가 다른 객체에 속하는 관계를 나타낸다. 집약 관계와의 명확한 차이는 합성 관계는 부분 객체가 전체 객체가 메모리에서 해제될 때 같이 해제된다는 것이다. 즉 큰 객체의 생명이 끝나면 부분 객체의 생명도 끝나게 된다.
위 클래스 다이어그램을 코드로 표현하면 아래와 같이 될 것이다.
class Human {
var liver = Liver()
deinit {
print("deinit human")
}
}
class Liver {
deinit {
print("deinit liver")
}
}
var human: Human? = Human()
human = nil
//deinit human
//deinit liver
참고로 markdown을 사용해서도 uml diagram을 그릴 수 있다. Markdown으로 여러 uml diagram을 그리는 방법은 아래의 plantuml 문서를 참고하면 될 것 같다.
간단한 텍스트를 이용하여 멋진 UML 다이어그램을 만들 수 있는 오픈소스 도구입니다.
간단한 텍스트를 이용하여 쉽게 멋진 UML 다이어그램을 만들 수 있으며, 다양한 종류의 다이어그램을 제공하고 있습니다. 또한, 생성된 다이어그램을 PNG, LaTeX, EPS, SVG 와 같은 이미지로 변환할 수
plantuml.com
참조
[UML] 클래스 다이어그램 작성법 - Heee's Development Blog
Step by step goes a long way.
gmlwjd9405.github.io
UML Class Diagram Tutorial
Learn UML Faster, Better and Easier Are you looking for a Free UML tool for learning UML faster, easier and quicker? Visual Paradigm Community Edition is a UML software that supports all UML diagram types. It is an international award-winning UML modeler,
www.visual-paradigm.com