반갑습니다!

[UML] Class Diagram 본문

개발

[UML] Class Diagram

김덜덜이 2020. 6. 22. 02:31

클래스 다이어그램을 그릴 때마다 기호가 헷갈렸던 적이 많았다. 복습도 할겸 정리를 해보았다.

클래스 / 객체 간의 관계

클래스 / 객체는 크게 연관 관계(Association), 의존 관계(Dependency), 집합 관계(Aggregation), 구성 관계(Composition)를 가진다.

연관 관계(Associtaion)

연관 관계란 서로 분리된 클래스가 연결을 가지는 것을 의미한다. 이는 단방향과 양방향이 있다. 그리고 각각의 객체는 독립적인 생명주기를 가진다. 또한 1:n, n:1, n:m의 관계를 가질 수 있다. 또한 객체에 대한 참조를 계속해서 유지하고 있다는 특징이 있다.

연관 관계의 표현 방법

클래스 다이어그램으로 표현할 때 연관 관계는 실선으로 표현한다. 단방향 관계의 경우 다른 객체를 참조하는 방향으로 화살표로 표기한다.

class Person(val name: String, val car: Car) {
    constructor(name: String) : this(name, Car())

    fun drive() {
        car.move()
    }
}

class Car {
    fun move() = println("차가 이동합니다.")
}

fun main() {
    val person = Person("Peter")
    person.drive()
}

위의 코드에서 Person클래스는 프로퍼티로 Car 객체를 1개 가지고 있다. 즉, Person과 Car는 1:1 관계이다. 그리고 Person이 Car를 참조하기 때문에 클래스 다이어그램으로 표현하면 다음과 같다.

의존 관계(Dependency)

의존 관계는 한 클래스가 다른 클래스에 의존되어 있어 영향을 주는 경우를 말한다. 한 곳이 변경되면 그것을 사용하는 다른 곳도 같이 변경해줘야 하는 관계를 표현할 때 주로 사용한다. 단, 주의해야 할 점은 연간 관계와 달리 의존 관계는 객체의 참조를 유지하고 있지 않는다는 점이다. 주로 다음과 같은 세 가지 경우에 의존 관계로 표현한다.

  1. 한 클래스의 메소드가 다른 클래스의 객체를 인자로 받아 그 메소드를 사용한다.
  2. 한 클래스의 메소드가 또 다른 클래스의 객체를 반환한다.
  3. 다른 클래스의 메소드가 또 다른 클래스의 객체를 반환한다. 이때 이 메소드를 호출하여 반환되는 객체의 메소드를 사용한다.

의존 관계의 표현

의존 관계가 있는 클래스는 점선으로 표현한다.

class Car {
    fun charge(pump: GasPump){
        pump.charge()
    }
}

class GasPump{
    fun charge() = println("기름을 충전합니다.")
}

fun main() {
    val car = Car()
    val pump = GasPump()
    car.charge(pump)
}

Car 객체는 기름을 충전하기 위해 GasPump 객체를 참조한다. 매개변수의 사용으로 GasPump 객체의 참조를 유지하지 않기 때문에 Car는 GasPump에 의존한다고 할 수 있다. 이를 클래스 다이어그램으로 표현하면 아래와 같다.

집합 관계(Aggregation)

집합 관계는 연간 관계에서 특정 객체를 소유한다는 개념이 추가된것이다.

집합 관계의 표현

집합 관계는 흰색 다이아몬드 모양으로 표기한다.

class Person(val name: String)

class Bus(val passengers: MutableList<Person>) {
    constructor() : this(mutableListOf())

    fun pickUpPassenger(person: Person) {
        passengers.add(person)
    }
}

fun main() {
    val bus = Bus()
    val person1 = Person("Peter")
    val person2 = Person("Steve")

    bus.pickUpPassenger(person1)
    bus.pickUpPassenger(person2)

    for(person in bus.passengers){
        print("${person.name} ")
    }
}

위 코드에서 Bus 객체는 여러 개의 Person 객체를 소유할 수 있다. 그리고 Bus에서는 Person을 참조할 수 있지만, Person은 Bus를 참조할 수 없기 때문에 다음과 같이 표현할 수 있다.

구성 관계(Composition)

구성 관계는 집합 관계와 다르게 두 객체의 생명 주기가 같다. 즉, 한 객체의 생명 주기가 다른 객체의 생명 주기를 의존한다고 할 수 있다.

구성 관계의 표현

구성 관계는 검은색 다이어몬드로 표현한다.

class Car(private var engine: Engine) {

    constructor() : this(Engine())

    fun startEngine() = engine.start()
    fun stopEngine() = engine.stop()
}

class Engine() {
    fun start() = println("엔진에 시동이 걸렸습니다")
    fun stop() = println("엔진에 시동이 꺼졌습니다")
}

fun main() {
    val car = Car()
    car.startEngine()
    car.stopEngine()
}

위 코드에서 Engine 객체는 Car 객체와 생명 주기를 같이 한다는 것을 알 수 있다. 위 코드를 클래스 다이어그램으로 표현하면 다음과 같다.

'개발' 카테고리의 다른 글

[JUnit 5] JUnit 5 - 2  (0) 2020.12.28
[JUnit 5] JUnit 5 - 1  (0) 2020.12.27
[Java] Java Reference  (0) 2020.10.15
[Java] Garbage Collection  (0) 2020.10.15
[Java] String 메모리 관리  (0) 2020.05.08