소프트웨어 모델을 통해 서로의 해석을 공유해 합의를 이루거나 해석의 타당성을 검토한다
현재 시스템 또는 앞으로 개발할 소프트웨어의 원하는 모습을 가시화하는데 도움을 준다
모델을 통해 소프트웨어 시스템의 구조와 행위를 명세할 수 있으며 시스템을 구축하는 틀을 제공한다
모델은 추상화에 바탕을 두고 만든다
추상화는 대상을 표현할 때 대상의 상세한 면을 있는 그대로 표현하지 않는다
특정 관점에서 관련이 있는 점은 부각시키고 관련이 없는 면은 무시하는 것이 필요하다
모델링은 시스템을 모델로 표현해주는 언어다
UM은 요구 분석, 시스템 설계, 시스템 구현 등의 시스템 개발 과정에서 의사 소통을 원할하게 이루어지도록 표준화한 언어다
분류 | 다이어그램 유형 | 목적 |
구조 다이어그램 (structure diagram) |
클래스 다이어그램 (class diagram) |
시스템을 구성하는 클래스들 사이의 관계를 표현 |
객체 다이어그램 (object diagram) |
객체 정보를 보여줌 | |
복합체 구조 다이어그램 (composite structure diagram) |
복합 구조의 클래스와 컴포넌트 내부 구조를 표현 | |
배치 다이어그램 (deployment diagram) |
소프트웨어, 하드웨어, 네트워크를 포함한 실행 시스템의 물리 구조를 표현 | |
컴포넌트 다이어그램 (component diagram) |
컴포넌트 구조 사이의 관계를 표현 | |
패키지 다이어그램 (package diagram) |
클래스나 유즈 케이스 등을 포함한 여러 모델 요소들을 그룹화해 패키지를 구성하고 패키지들 사이의 과정을 표현 | |
행위 다이어그램 (behavior diagram) |
활동 다이어그램 (activity diagram) |
업무 처리 과정이나 연산이 수행되는 과정을 표현 |
상태 머신 다이어그램 (state machine diagram) |
객체의 생명주기를 표현 | |
유즈 케이스 다이어그램 (use case diagram) |
사용자 관점에서 시스템 행위를 표현 | |
순차 다이어그램 (sequence diagram) |
시간 흐름에 따른 객체 사이의 상호작용 표현 | |
상호작용 개요 다이어그램 (interaction overview diagram) |
여러 상호작용 다이어그램 사이의 제어 흐름을 표현 | |
통신 다이어그램 (communication diagram) |
객체 사이의 관계를 중심으로 상호작용을 표현 | |
타이밍 다이어그램 (timing diagram) |
객체 상태 변화와 시간 제약을 명시적으로 표현 |
UML에서는 시스템의 구조와 동작을 표현하는 다이어그램을 제공한다
다양한 다이어그램으로 다양한 관점에서 시스템을 모델링하기 위함이다
클래스 다이어그램은 시스템의 정적인 면을 보여주는 대표적인 UML 구조 다이어그램이다
클래스 다이어그램은 시스템을 구성하는 사이의 관계를 보여준다
주요 구성 요소는 클래스와 관계다
클래스는 공통의 속성과 책임을 갖는 객체들의 집합이자 실제 객체를 생성하는 설계도다
UML에서는 다음처럼 클래스를 표현한다
가장 윗부분에는 클래스 이름을, 중간 부분에는 클래스의 특징을 나타내는 속성을, 마지막 부분에는 클래스가 수행하는 책임, 연산을 기술한다
경우에 따라 속성 부분이나 연산 부분은 생략할 수 있다
-
나 +
와 같은 부호는 속성과 연산의 가시화를 정의한다
접근 제어자 | 표시 | 설명 |
---|---|---|
public | + | 어떤 클래스의 객체에서든 접근 가능 |
private | - | 이 클래스에서 생성된 객체들만 접근 가능 |
protected | # | 이 클래스와 동일 패키지에 있거나 상속 관계에 있는 하위 클래스의 객체들만 접근 가능 |
package | ~ | 동일 패키지에 있는 클래스의 객체들만 접근 가능 |
속성과 연산에 가시화 정보를 항상 표시해야 하는 것은 아니다
클래스 하나로만 이루어진 시스템은 존재하지 않는다
객체지향 시스템은 여러 개의 클래스가 서로 긴밀한 관계를 맺어 기능을 수행한다
다음은 UML에서 제공하는 클래스들 사이의 관계다
관계 | 설명 |
---|---|
연관 관계 (association) | 클래스들이 개념상 서로 연결되었음을 나타낸다 |
일반화 관계 (generalization) | 상속 관계다 |
집합 관계 (composition, aggregation) | 클래스들 사이의 전체 또는 부분 같은 관계를 나타낸다 |
의존 관계 (dependency) | 한 클래스가 다른 클래스에서 제공하는 기능을 사용할 때를 나타낸다 |
실체화 관계 (realization) | 인터페이스와 이 를 구현한 클래스들 사이의 관계를 나타낸다 |
UML에서 연관 관계는 클래스 사이에 선을 그어 표시한다
한 클래스가 다른 클래스와 연관 관계를 가지면 각 클래스의 객체는 어떤 역할을 수행한다
이런 역할은 연관 관계를 나타내는 선 가까이에 적을 수 있다
이 연관 관계는 양방향 연관 관계다
양방향 연관 관계는 UML에서 두 클래스를 연결한 선에 화살표를 사용하지 않는다
두 클래스의 객체들이 서로의 존재를 인식한다
연관 관계는 방향성을 가질 수 있다
Student는 자신이 수강하는 Course를 알지만, Course는 잔신을 수강하는 Student 존재를 모른다
이렇게 한쪽으로만 방향성이 있는 연관 관계를 단방향 연관 관계라 한다
여러 명의 학생이 수강할 수 있는 일반적인 수강 관계로 개선하면 다음과 같다
이를 다대다 연관 관계라고 한다
다대다 연관 관계는 양방향 연관 관계가 되므로 구현하기가 복잡하다
따라서 보통 다대다 연관 관계를 일대다 단방향 연관 관계로 변환해 구현한다
연관 클래스를 사용해 풀어낸다
성적 정보는 Student, Course 어디에도 둘 수가 없다
성적은 Student, Course 두 클래스 객체가 존재해야만 의미 있는 정보가 되기 때문이다
예를 들어 홍길동 학생이 A+
라는 말은 어색하다
어떤 과목에서 A+를 받았다는 정보가 누락되기 때문이다
마찬가지로 소프트웨어 공학이 A+
라는 말도 어색하다
성적 정보는 클래스의 속성이 아닌 수강하다라는 연관 관계의 속성으로 다뤄야 한다
이런 경우 연관 클래스를 사용한다
연관 클래스를 일반 클래스로 변환하면 다음과 같아진다
연관 관계는 때로 재귀적일 수 있다
재귀적 연관 관계란 동일한 클래스에 속한 객체들 사이의 관계다
예를 들어 직원 클래스가 있고, 직원들 중에는 관리자 역할을 하는 직원도 있고 사원 역할을 하는 직원도 있다
현실에서는 관리자 한 명이 여러 사원들을 관리한다
때로는 관리해야 하는 사원이 전혀 없는 관리자가 있을 수 있고, 역으로 어떤 사원은 관리자가 없을 수도 있다
이 때 문제가 발생한다
즉 관리자와 사원 역할을 클래스로 만들면 시스템이 변화할 때 유연성이 부족해진다
가급적 역할을 클래스로 만들지 않는 것이 좋다
이를 해결하기 위해 재귀적 연관 관계가 생겨났다
홍길동이 홍길서를 관리하고 홍길서과 홍길남을 관리하는 상황에서 홍길남이 홍길동을 관리하는 상황이 있을 수 잇다
이를 관계 루프라고 하며 이런 상황을 배제하기 위해 연관 관계에 제약을 설정해야 한다
제약은 {}
안에 UML 모델 요소가 따라야 하는 규칙을 붙여줄 때 사용한다
{계층}이라는 제약은 객체 사이에 상하 관계가 존재하고 사이클이 존재하지 않는다는 의미다
객체지향 개념에서 일반화 관계를 상속 관계라 한다
가전 제품과 세탁기 사이의 관계 or TV, 식기세척기와 가전 제품의 관계는 모두 가전 제품과 is a kind of 관계
다
UML에서 일반화 관계는 다음과 같이 표현한다
두 클래스를 연결하는 화살표의 끝에 빈삼각형 표시를 해 표현한다
집합 관계는 UML 연관 관계의 특별 경우로 전체와 부분의 관계를 명확하게 명시하고자 할 때 사용한다
집약(aggregation)과 합성(composition) 두 종류의 집합 관계가 존재한다
집약 관계는 한 객체가 다른 객체를 포함하는 것을 나타낸다
전체-부분 관계이다
전체를 가르키는 클래스 방향에 빈 마름모로 표시한다
부분을 나타내는 객체를 다른 객체와 공유할 수 있는 경우에 집약 관계로 나타낸다
전체 객체의 라이프사이클과 부분 객체의 라이프사이클은 독립적이다
합성 관계는 전체를 가리키는 클래스 방향에 채워진 마름모로 표시되며 부분 객체가 전체 객체에 속하는 관계다
전체 객체가 사라지면 부분 객체도 사라진다
코드를 통해 집약 관계와 합성 관계를 구분할 수 있다
public class Computer {
private MainBoard mb;
private CPU c;
private Memory m;
private PowerSupply ps;
public Computer() {
mb = new MainBoard();
c = new CPU();
m = new Memory();
ps = new PowerSupply();
}
}
이 코드에서 Computer 클래스의 객체가 사라지면 멤버도 같이 사라진다
즉 부품 객체들의 라이프사이클이 Computer 객체의 라이프사이클에 의존한다
이는 합성 관계로 모델링한다
다음 코드를 본다
public class Computer {
private MainBoard mb;
private CPU c;
private Memory m;
private PowerSupply ps;
public Computer(MainBoard mb, CPU c, Memory m, PowerSupply ps) {
this.mb = mb;
this.c = c;
this.m = m;
this.ps = ps;
}
}
Computer 객체가 사라져도 부품을 구성하는 MainBoard 객체, CPU 객체, Memory 객체, PowerSupply 객체는 사라지지 않는다
외부에서 참조만 받아 사용하기 때문이다
따라서 집약 관계를 사용하여 모델링 한다
집약 관계와 합성 관계를 구분하려면 전체 객체와 부분 객체의 라이프사이클 의존성을 살펴본다
일반적으로 한 클래스가 다른 클래스를 사용하는 경우는 다음과 같이 3가지가 있다
한 클래스의 객체를 다른 클래스 객체의 속성에서 참조하는 경우에, 참조하는 객체가 변경되지 않는 한 두 클래스의 객체들이 협력 관계를 통해 기능을 수행한다
예를 들어, 자동차(Car 클래스)를 소유한 사람(Person 클래스)이 자동차를 이용해 출근한다고 할 경우 같은 자동차를 계속 사용할 것이다
이런 경우 Person 클래스와 Car 클래스는 연관 관계며 Person 클래스의 속성으로 Car 객체를 참조한다
자동차와 주유기(GasPump 클래스)의 관계는 다르다
자동차에 주유할 때마다 특정 주유소의 특정 주유기만 사용할 수 없다
이런 경우 매번 달라지는 주유기를 사용할 것이며 객체지향 프로그램에서는 주유기를 인자나 지역 객체로 생성해 구현한다
UML에서 의존 관계를 점선으로 나타낸다
연관 관계는 오랜 시간 동안 같이할 객체와의 관계며 의존 관계는 짧은 시간 동안 이용하는 관계다
인터페이스는 책임이다
객체의 책임이란 객체가 해야 하는 일로서 해석할 수 있고 객체가 할 수 있는 일로도 해석할 수 있다
즉, 객체가 외부에 제공하는 서비스나 기능은 객체가 수행하는 책임으로 보는 것이다
예를 들어 TV 리모콘은 TV를 켜거나 끄거나 볼륨을 높이거나 낮추거나와 같은 책임을 수행해야 한다
인터페이스를 공통되는 능력이 있는 것들을 대표하는 관점으로도 볼 수 있다
비행기와 새는 공통적으로 날 수 있는 능력이 있다
이런 공통 능력 관점에서 비행기와 새를 그룹화할 수 있는 매커니즘이 바로 인터페이스다
인터페이스 자체는 실제로 책임을 수행하지 않는다
비행기나 새와 같은 객체들이 책음을 실제로 수행한다
UML에서는 인터페이스와 구현 클래스의 관계를 상속과 유사하게 빈 삼각형을 머리에 있는 실선 대신 점선을 사용해 표시한다
또한 <<interface>>
라고 스테레오 타입을 적는다
일반화 관계는 is a kind of, 실체화 관계는 can do this