본문 바로가기
프로그래밍/기타

[UML] 클래스 다이어그램 이해하기

by 사바라다 2020. 3. 29.

[UML] 클래스 다이어그램 이해하기
[UML] 시퀀스 다이어그램 이해하기

안녕하세요. 오늘은 클래스 다이어그램에 대해서 이야기 해보고자 합니다. 최근 레거시 시스템의 구조개선을 조금씩 하고 있습니다. 그러면서 객체의 구성 및 도메인 모델을 어떻게 가져가야할지 고민을 하게 되었습니다. DDD 관련된 책이라던지 찾아보는데 이때 기본이 되는게 UML, 특히 클래스 다이어그램 이라는 것을 알 수 있었습니다. 지끔까지는 막연한 지식은 있지만 이번 기회에 명확하게 이를 이해하고자 UML, 그 중에서도 클래스 다이어그램에 대해서 정리해보고자 합니다.

UML 이란

먼저 UML이란 Unified Modeling Language의 약자로 도메인(해결하고자 하는 목표, ex) 결재시스템 등)을 모델로 표현해주는 대표적인 모델링 언어로 알려져 있습니다. 이런 UML은 소프트웨어를 설계하며 필요에 의해서 사용되는데 일반적으로 아래 3가지의 목적을 가지고 만듭니다.

  • 의사소통 또는 설계 논의를 위해
  • 전체 시스템의 구조 및 클래스의 의존성 파악을 위해
  • 유지보수를 위한 설계의 back-end 문서 제작을 위해

클래스 다이어그램

UML 중에서도 오늘 알아 볼 클래스 다이어그램은 정적 다이어그램으로 클래스의 구성요소 및 클래스간의 관계를 표한하는 대표적인 UML입니다. 이를 통해 시스템의 일부 또는 전체의 구조를 나타낼 수 있습니다. 그리고 클래스 다이어그램을 이용하면 의존 관계를 명확히 보게 해주며, 순환 의존이 발생하는 지점을 찾아내서 어떻게 이 순환고리를 깰 수 있을지 결정할 수 있게 해줍니다.

클래스 다이어그램은 2가지 용도로 사용될 수 있습니다. 첫번째는 문제 해결을 위한 도메인 구조를 나타내어 보이지 않는 도메인 안의 개념과 같은 추상적인 개념을 기술하기 위해 나타낸 것입니다. 두번째는 소프트웨어의 설계 혹은 완성된 소프트웨어의 구현 설명을 목적으로 사용할 수 있습니다. 아래 이미지의 왼쪽이 첫번째 목적을 위해 사용하는 방법이며 오른쪽이 두번째 목적을 위해 사용하는 방법입니다.

클래스 다이어그램의 활용

클래스 다이어그램의 기본 요소

클래스 다이어그램을 그리기 위한 기본요소에 대해서 알아보도록 하겠습니다. 클래스에는 클래스의 이름, 속성, 그리고 메서드가 존재합니다. 이런 요소들은 어떻게 클래스 다이어그램에 표현할 수 있을 까요?

접근제어자 리스트

  • + : public
  • - : private
  • # : protected

형식

  • 속성(Attribute)
    • 접근제어자 이름: 타입 = 기본값
    • ex) -title: String = ""
  • 메서드
    • 접근제어자 이름(파라미터 속성): 리턴값
    • ex_1) +setTitle(String)
    • ex_2) +getTitle(): String

interface와 abtsract(추상화)와 같은 요소들은 <<>>을 이용해서 <<interface>> 또는 <<abstract>>로 나타낼 수 있습니다. 이렇게 기본적인 요소를 알아보았습니다.

클래스 다이어그램을 이용한 관계 표현

참조 : http://www.nextree.co.kr/p6753/

클래스간의 연관관계는 위 7가지로 나타낼 수 있습니다. 각각이 어떤 관계를 의미하는지, 그리고 클래스 다이어그램으로 어떻게 표현되는지 알아보도록 하겠습니다.

Generalization ( 일반화 )

Generalization은 우리가 일반적으로 알고 있는 상속을 의미합니다. 이는 클래스 다이어그램에서는 실선에 비어있는 화살표로 표시합니다.

이러한 도메인 모델을 코드로 구현하면 아래와 같습니다.(get, set 메서드는 생략하도록 하겠습니다.)

public class Board {
    private String title;
    private String contents;
    private List<Comment> comments;

    // 기본 getter / setter 메서드들
}

class SchedulerBoard extends Board {
    private LocalDate startDate;
    private LocalDate endDate;

    public void validateDateLine() {
        ...
    }
}

Realization ( 실체화 )

Realization은 interface에 있는 spec을 오버라이딩하여 실제로 구현하는 것을 말합니다. Realization은 점선과 비어있는 화살표로 표현합니다.

위 다이어그램의 오른쪽과 왼쪽은 모두 동일한 의미를 가집니다. 코드로 구현하면 아래와 같습니다.(Board의 attribute는 구현 생략하였습니다.)

public interface OpenCloseable {
    void open();
    void close();
}

public class Board implements OpenCloseable {
    public void open() {
        System.out.println("open method");
    }

    public void close() {
        System.out.println("close method");
    }
}

Dependency ( 의존 )

Dependency는 클래스간의 참조가 일어나는 것 중 하나입니다. Dependency 참조는 메서드 내에서 대상 클래스의 객체를 생성하거나 사용, 리턴받아 사용하는 것을 말합니다. 그리고 이 참조는 해당 클래스와의 관계를 계속 유지하지 않습니다. dependency는 점섬과 화살표로 이루어져 있습니다.

코드로 표현하면 아래와 같습니다.

public class Board {

    private String title;

    public String getTitleWithRanking(Ranking ranking) {
        return title + ranking.getRank();
    }
}

public class Ranking { 
    private int rank;

    public int getRank() {
        return rank;
    }
}

Dependency는 메서드의 호출이 끝나면 연관된 클래스와의 관계가 마무리된다는 것이 중요합니다.

Association & Direct Association ( 연관 )

클래스 다이어그램에서의 Association은 다른 객체의 참조를 가지는 필드를 의미합니다. 실선으로 표현되며 방향성이 존재하는 경우에는 화살표를 넣어 표시합니다. 그리고 둘의 연관관계가 어떻게 되는지 숫자로 표시할 수 있습니다.

연관관계의 숫자 표현은 아래와 같이 합니다.

  • 1 - 1개의 표현
  • * - 0 ~ n 개의 표현
  • n...m : n 부터 m까지 연관관계를 맺음

아래 예제는 양방향 연관관계를 가지며 1(Board) : n(Comment)의 관계를 표시한 것입니다.

아래의 코드는 위의 이미지를 코드로 구현한 것입니다.

public class Board {

    private List<Comment> comments;

    public void addComment(Comment comment) {
        comments.add(comment);
    }
}

public class Comment {

    private Board board;

    public void setBoard(Board board) {
        this.board = board;
        board.addComment(this);
    }
}

Aggregation ( 집합 ) & Composition (합성)

클래스 다이어그램에서 Aggregation과 Composition은 Association의 특수한 관계입니다. Aggregation은 Association의 집합관계를 나타내는 것으로 Collection이나 Array를 이용하는 관계입니다. 하지만 이 관계는 일반적인 Association으로도 충분히 나타낼 수 있는 관계입니다. 우리가 위에서 Association의 예제가 바로 1 : N 연관관계를 나타낸 것입니다. Aggregation과 Association의 모호성은 지속적으로 논란이 되고 있지만 결론이 나지 않았다고 합니다. 논란

Aggregation은 실선에 빈 다이아몬드로 나타냅니다.

Composigiton은 클래스 연관관계에서 강한 결합의 관계를 의미합니다. 즉, 참조하는 클래스의 라이프 사이클이 종속적이라는 말입니다. 다이어그램으로는 실선에 채워져있는 다이아몬드로 표시합니다.

조금 억지스럽기는 하지만 rank class Board에 종속적인 상황입니다. 코드는 아래와 같습니다.

public class Board {
    private Ranking rank;

    public Board() {
        rank = new Rank();
    }

    public void calculateRanking() {
        System.out.println(rank.calculateRanking());
    }
}

public class Ranking {
    private int rank;

    public int calculateRanking() {
        ... [logic] ...
        return rank;
    }
}

위코드는 Rank class가 rank를 관리하며 관련 class를 Board에서 생성하고 사용하는 코드입니다. 이렇게 되면 Board가 사용하지 않는 경우가 발생했을때 자연스럽게 Rank도 참조가 불가능한 상태가 됩니다. 일반적인 Association(Aggregation) 상황에서는 외부에서 가져오기 때문에 1번 Board Class가 죽더라도 Comment의 경우 다른곳에서 참조할 수 있는것과 다릅니다.

마무리

오늘은 이렇게 UML 중 클래스 다이어그램에 대해서 알아보았습니다. 클래스 다이어그램은 소프트웨어 구조 분석에 기본이 되는 지식으로 알아두시면 도움이 되실 것 같습니다.

감사합니다.

참조

http://www.nextree.co.kr/p6753/

https://nirajrules.wordpress.com/2011/07/15/association-vs-dependency-vs-aggregation-vs-composition/

댓글