[UML Distilled] 3장

3장. 클래스 다이어그램 : 필수 요소

클래스 다이어그램

  • 시스템의 객체의 타입과 그들 간에 존재하는 다양한 정적 관계에 대해서 기술한다.
  • 클래스의 프로퍼티(property)오퍼레이션(operation), 객체들이 연결되는 방법에 적용되는 제약사항(constraints) 을 보여준다. 3.1
    그림 3.1 단순한 클래스 다이어그램

프로퍼티

  • 클래스의 구조적인 특징을 나타낸다.
  • 클래스의 필드(field)에 대응된다.
  • 단일 개념이지만 두 가지의 다른 표기법으로 나타난다.

속성

  • 클래스 상자 안에 한 줄의 텍스트로 표시되는 프로퍼티다.

가시성 이름 : 타입 다중성 = 기본 값 {프로퍼티 문장}

  • 가시성(visibility) : 속성이 public(+)인지 private(-)인지를 나타낸다.
  • 이름 : 클래스에서 어떻게 속성을 참조할지 나타낸다. 필드 이름과 대략 같은 것이다.
  • 타입(type) : 속성에 들어갈 수 있는 객체의 종류를 한정한다. 필드 타입과 같은 것이다.
  • 기본 값(default) : 속성의 값이 지정되지 않으면 기본적으로 갖게 되는 값이다.
  • 프로퍼티 문장(property-string) : 속성에 대한 추가 프로퍼티를 나타낸다.

3.2

그림 3.2 order의 프로퍼티를 속성으로 나타낸 것

연관

  • 두 클래스 사이의 실선으로 표시되며, 소스 클래스에서 타겟 클래스를 향한다.
  • 프로퍼티의 이름은 연관의 타겟 쪽 끝 쪽에 다중성과 함께 표시된다.
  • 연관의 타겟 쪽 끝은 프로퍼티의 타입이 되는 클래스와 연결된다.

img

그림 3.3 order의 프로퍼티를 연관으로 나타낸 것

다중성

  • 얼마나 많은 개체가 프로퍼티에 들어갈 수 있는지를 나타낸다.
    • 1 (하나의 주문은 단 하나의 고객만을 가져야 한다.)
    • 0..1 (기업 고객은 한 명의 판매 담당자를 갖거나 갖지 않을 수 있다.)
    • * (고객은 주문을 하지 않아도 되며, 주문할 수 있는 개수의 제한도 없다. 즉, 0개 이상의 주문이 가능하다.)
  • 다중성은 하한(lower bound)상한(upper bound) 을 정한다.
    • 선택(Optional) : 하한이 0임을 의미한다.
    • 필수(Mandatory) : 하한이 1 이상임을 의미한다.
    • 단일 값(Single-valued) : 상한이 1임을 의미한다.
    • 다중 값(Muiltivalued) : 상한이 1 이상(흔히 *)임을 의미한다.
  • 만약 순서가 의미가 있다면 연관의 끝에 {ordered} 를 붙인다.
  • 중복을 혀용한다면 {nonunique} 를 붙인다.

프로퍼티의 프로그래밍적인 해석

  • 속성의 가장 일반적인 소프트웨어 표현은 프로그래밍 언어의 필드나 프로퍼티이다.
  • 읽기 전용 속성은 설정하는 메소드(필드의 경우)나 set 액션(프로퍼티의 경우)을 가짖 ㅣ않는다.
  • 속성이 다중 값이라는 것은 데이터가 컬렉션(collection) 이라는 것을 암시한다.
  • 프로퍼티란 객체가 항상 제공할 수 있는 어떤 것을 의미한다.

양방향 연관

  • 양방향 연관이란 서로 반대로 연결된 한 쌍의 프로퍼티다.

3.4

그림 3.4 양방향 연관

  • 연관에 프로퍼티의 이름을 붙이는 대신, 동사형으로 이름을 붙여서 연관을 문장으로 표현한다.
  • 이것이 책임(responsibility)오퍼레이션에 더 잘 대응한다.

3.5

그림 3.5 연관의 이름을 동사형으로 붙인 예

오퍼레이션

  • 오퍼레이션(operation) 이란 클래스가 수행하는 액션이다.

가시성 이름 (매개변수 리스트) : 리턴 값 타입 {프로퍼티 문장}

  • 가시성(visibility) : public(+)와 private(-)가 있다.
  • 이름(name) : 이름을 나타낸다.
  • 매개변수 리스트(parameter-list) : 오퍼레이션에 사용되는 매개변수의 목록이다.
  • 리턴 값 타입(return-type) : 리턴 값의 타입이다.
  • 프로퍼티 문자열(property-string) : 오퍼레이션에 적용되는 프로퍼티 값들을 의미한다.
  • 매개변수들은 다음과 같이 기술된다.

방향 이름 : 타입 = 기본 값

  • 이름(name), 타입(type), 기본 값(default) 은 속성과 같다.
  • 방향(direction) 은 매개변수가 입력(in)인지 출력(out)인지 입출력(inout)인지를 나타낸다. 만약 표시되지 않으면 입력으로 간주된다.
  • 쿼리(query) : 시스템의 상태를 바꾸지 않고 클래스의 값을 가져가는 오퍼레이션
  • 변경자(modifier), 커맨드(command) : 상태를 변화시키는 오퍼레이션
  • 쿼리와 변경자의 차이는 관찰 가능한 상태(observable state) 를 변경하는지의 여부이다.
    • 관찰 가능한 상태란 외부에서 인지할 수 있는 상태를 말한다.
  • 커맨드-쿼리 분리 원칙(Command-Query seperation principle)
    • 일반적인 관례는 변경자가 값을 리턴하지 않도록 작성하는 것이다.
    • 값을 리턴하는 오퍼레이션은 쿼리라는 사실을 믿을 수 있다.
  • 오퍼레이션은 객체에서 호출되는 것(프로시저의 정의)이다.
  • 메소드는 프로시저의 본체이다.

일반화

  • 소프트웨어 관점에서, 일반화는 상속과 명확한 연관이 있다.
  • 상속을 효과적으로 사용하기 위한 중요한 원칙은 치환 가능성(substitutability) 이다.
    • Liskov 치환 원리(Liskov Substitution Principle: LSP) : 하위 타입(subtype)은 항상 자신의 기반 타입(base type)으로 교체할 수 있어야 한다.
  • 상위 타입을 치환할 수 있는 클래스는 하위 타입(subtype) 이고, 하위 클래스(subclass) 는 일반적인 상속과 같은 말이다.

노트와 주석

  • 노트(note) 는 다이어그램에 있는 주석이다.

3.6

그림 3.6 노트는 하나 이상의 다이어그램 요소에 대한 주석으로 쓰인다.

의존

  • 두 요소 사이에 의존(dependency) 이 존재한다는 것은 어떤 요소(공급자 또는 타겟)의 정의에 대한 변화가 다른 요소(클라이언트 또는 소스)의 변화를 유발한다는 것을 의미한다.
    • ex) 클래스 간 메세지 전송, 어떤 클래스가 오퍼레이션의 매개변수로 다른 클래스를 사용하는 등
  • 의존을 통제하는 데에 실패하면, 시스템에 대해서 변경을 할 때마다 많은 부분을 변경해야한다.

image.png

그림 3.7 의존의 예

  • 의존은 한 방향으로만 이루어져야 한다.
  • UML에는 각각 특별한 의미와 키워드를 가진 다양한 종류의 의존이 있다.
키워드 의미
<<call» 소스가 타겟의 오퍼레이션을 호출한다.
<<create» 소스가 타겟의 인스턴스를 생성한다.
<<derive» 소스가 타겟으로부터 파생된다.
<<instantiate» 소스는 타겟의 인스턴스이다. (소스가 클래스라면, 클래스 자체가
‘클래스’ 클래스의 인스턴스임을 기억하라. 즉, 타겟 클래스는
메타 클래스이다.)
<<permit» 소스가 타겟의 private 특성들에 접근할 수 있다.
<<realize» 소스가 타겟에서 정의한 명세 또는 인터페이스를 구현한다.
<<substitute» 소스는 타겟과 치환 가능하다.
<<refine» 정제(refinement)란 서로 다른 의미 단계(semantic level) 사이의
관계를 의미한다. 예를 들어 소스는 설계 클래스이며 타겟은
해당되는 분석 클래스인 경우.
<<trace» 클래스에 대한 요구 사항을 추적하거나, 한 모델의 변경 사항이
다른 곳에 어떻게 영향을 주는지를 추적할 때 사용한다.
<<use» 구현을 위해서 소스가 타겟을 필요로 한다.

표3.1 의존에 사용할 수 있는 키워드의 일부

  • 의존을 가능한 줄이는 것을 기본적인 규칙으로 삼아야 한다.
  • 특히 순환에 주의해야 하는데, 변경의 순환(cycle of change) 이 일어날 수 있기 때문이다.
  • 전달하고자 하는 특별한 주제와 밀접한 관계가 있을 때만 선택적으로 의존을 사용한다.

제약 규칙

  • 제약을 설명하기 위한 유일한 규칙은 제약을 중괄호({}) 안에 넣는 것이다.
  • 이름을 먼저 쓰고 콜론(:) 을 넣어서 제약에 이름을 붙일 수 있다.

클래스 다이어그램을 언제 사용하는가

  • 클래스 다이어그램을 사용할 때 가장 위험한 것은 구조에 지나치게 집착하여 행동을 무시하는 것이다.
  • 소프트웨어를 이해하기 위해서 클래스 다이어그램을 그린다면 행동에 집중하여 그리도록 하여라.

Leave a comment