UML 객체지향 설계/ 전체 정리

객체지향을 이해합시다

객체

하나의 객체는 구조 (Structure)를 가지고 있다. 쉽게 말해서 속성 (Attribute)과 행동 (Behavior)을 가지고 있다는 뜻이다. 객체의 행동은 자신이 수행하는 오페레이션 (Operation)으로 구성되어 있다. 속성과 오퍼레이션을 모두 합쳐서 특성 (Feature)이라고 한다.

객체는 클래스의 인스턴스이다. 클래스는 동일한 속성과 오퍼레이션을 가지고 있는 객체의 일반적인 범주를 뜻한다. 클래스는 객체를 생성하는 틀, 혹은 템플릿 (Template)이기도 하다.

객체지향의 목적은 실세계의 일부 혹은 전체를 본 뜨는 것(이것을 모델링이라고 한다)이라는 점이다. 속성과 오퍼레이션들이 좀 더 많이 반영된 클래스일수록 실세계에 더 가까운 모델이 만들어진다.

객체지향을 이루는 몇 가지 개념들

추상화

추상화 (Abstraction)란 객체를 모델링할 때 여러분이 필요로 하는 만큼의 속성과 오퍼레이션을 추출해 내는 것이다. 전문가들은 추상(모델에 무엇을 포함하고 무엇을 뺄 것인지를 아는 것)이 모델을 만드는 사람에게 있어 가장 중요한 기술이다라고 주장한다.

상속

세탁기, 냉장고, 전제레인지 등은 모두 가전제품이다. 이들은 각각 가전제품이라는 클래스의 서브클래스 (Subclass)라고 할 수 있으며, 가전제품이라는 클래스는 각각의 제품의 슈퍼클래스 (Superclass)가 된다.

객체지향에서 이러한 관계를 상속 (Inheritance)이라고 한다. 가전제품 클래스의 각 서브클래스(세탁기, 냉장고, 전자렌지 등)는 가전제품의 모든 특성을 물려받게 된다. 중요한 점은 각각의 서브클래스는 자신만의 속성과 행동을 추가한다는 것이다.

다형성

다른 클래스인데 같은 이름의 오퍼레이션을 가지게 되는 경우가 있다. 예를 들어 같은 Open인데도 문을 열고(Open Door), 창문을 열고(Open Window), 신문을 펼치고(Open Newspaper), 은행 계좌를 개설하고(Open Account), 대화를 시작하는 데(Open Conversation) 모두 이 동사를 사용할 수 있는 것이다. 행위의 대상이 모두 다르기 때문에 다른 오퍼레이션이 이루어지는 것이다. 객체지향 세계에서는 각각의 클래스마다 자신의 오퍼레이션이 어떻게 행동하는지를 알고 있다. 이것을 다형성 (Polymorphism)이라고 한다.

다형성은 동일한 이름의 오퍼레이션이라도 그 오퍼레이션이 일어나는 클래스에 따라 각기 다른 행동을 수행하도록 한다. 예컨대 같은 이동이라는 명령을 수행할 때 땅에서는 달리기를 하고 물에서는 수영을 한다.

캡슐화

객체는 자신의 오퍼레이션을 수행하고 결과를 내놓지만 그 오퍼레이션의 동작 원리는 가려져 있다.

객체는 자신의 동작 원리를 클래스라는 껍데기로 캡슐화 (Encapsulation)한다. 즉, 그 객체만이 자신의 오퍼레이션이 어떻게 작동하는지를 알고 있으며 외부에서는 알 수 없다. 이래서 캡슐화를 정보 은닉이라고도 부른다. 하지만 모든 것을 숨긴다면 객체는 아무 의미도 없다. 객체는 얼굴(face)만을 보임으로써 그 객체가 수행하는 오퍼레이션을 다른 객체나 외부 세계에서 지시할 수 있도록 한다. 이것을 인터페이스 (interface)라고 한다.

메세지 전송

시스템 안에서는 객체들이 서로 연결되어 행동한다. 객체들은 어떻게 서로 손발을 맞추어 행동하는 것일까? 바로 메세지를 사용하는 것이다. 한 객체가 다른 객체에게 메세지를 보내어 어떤 오퍼레이션을 수행하도록 하면 메세지를 받은 객체는 지시 받은 대로 해당 오퍼레이션을 수행하는 것이다.

연관

객체지향 세계에서 흔히 벌어질 수 있는 또 한 가지는 한 객체가 다른 객체와 관계를 맺는 것이다. 예를 들어 여러분이 TV를 켜는 일을 객체지향적으로 해석하면 여러분은 TV와 연관 (Association) 관계에 있게 되는 것이다.

TV를 켜는 것에 대한 연관은 단방향성(Unidirectional)이다. 결혼하는 것에 대한 연관은 양방향성(Bidirectional)이다.

한 객체가 다른 객체와 가지는 연관이 두 개 이상일 경우도 있다. 친구와 동업을 하고 있다면 친구라는 연관과 동업자라는 연관을 동시에 가지게 되는 것이다.

하나의 클래스는 한 개 이상의 다른 클래스와 연관될 수 있다. 사람은 자동차에 탈 수 있을 뿐만 아니라 버스에도 탈 수 있다.

다중성 (Multiplicity)은 객체 사이의 연관 관계를 설명할 때 매우 중요한 특징이다. 다중성은 특정한 집합 내에서 하나의 객체가 몇 개의 객체와 연관될 수 있는지를 알려준다.

집합연관

컴퓨터는 또 다른 타입의 연관 관계인 집합연관 (Aggregation) 관계에 있다. 컴퓨터는 수많은 구성요소로 이루어져 있기 때문이다.

집합체(Aggregate) 전체와 그 객체를 구성하는 컴포넌트 부분끼리 밀접한 관계를 가지는 집합연관의 한 형태가 있는데 이것을 복합연관 (Composition)이라고 한다. 복합연관의 열쇠는 바로 컴포넌트가 복합체(Composite)에서만 컴포넌트로써 존재한다는 점이다. 예를 들어 셔츠는 몸통, 칼라, 소매, 단추 등의 복합체이다. 셔츠와 칼라를 떼어 놓으면 아무 의미도 없다.

가끔 복합체 내의 컴포넌트는 복합체만큼 오래 가지 않는 경우도 있다. 나무에 붙어 있는 잎은 나무가 죽기 전에 떨어져 나갈 수 있는 것이다. 물론 나무를 찍어 넘어뜨리면 잎은 따라서 죽는다.

집합연관과 복합연관이 없으면 실세계의 객체를 그대로 모델링하기가 거의 불가능하다. 실세계의 객체는 여러 개의 부분이 모여서 전체를 이룬 형태가 부지기수이기 때문이다.

객체지향 개념을 적용해 봅시다

속성

속성 (Attribute)이란 클래스에 속한 특성에 이름을 붙인 것으로 이것이 가질 수 있는 값의 범위를 설정한다. 클래스는 0개 이상의 속성을 가질 수 있다

오퍼레이션

오퍼레이션 (Operation)이란 객체에게 요청할 수 있는 행동을 말한다.

오퍼레이션이름 뒤에 따라오는 괄호 안에 매개변수 (Parameter) 리스트를 넣어줄 수 있는데 하나의 매개변수는 “이름:타입”의 형태를 가진다. 오퍼레이션 중에 자신의 작업을 마친 후에 그 결과를 반환하는 형태가 있는데 이러한 오퍼레이션을 함수 (Function)이라고 한다

클래스 모델링은 이렇게 시작하자

몸담고 있는 업무에서 사용되는 명사(noun)에 특히 귀를 쫑긋이 세우고 있어야 한다. 이 명사들은 여러분이 모델링할 클래스의 이름이 될 가능성이 높다. 그들이 말하는 동사(verb)도 놓치지 말자. 그것들은 모델링한 클래스의 오퍼레이션이 될 후보들이다.

관계를 지어 봅시다

연관

클래스가 개념적으로 서로 연결되어 있을 때 이 관계를 연관 (Association)이라고 부른다.

연관에 대한 제약

두 클래스 사이의 연관 관계가 어떠한 규칙을 따라야 할 경우가 있다.

연관 클래스

연관은 클래스와 같이 속성과 오퍼레이션을 가질 수 있다. 속성과 오퍼레이션을 가진 연관은 연관 클래스 (Association Class)라는 이름으로 따로 구분한다. 예를 들어 만일 선수와 팀이 고용주와 고용자로서 계약이라는 연관을 가질 경우 계약은 연봉이나 기간 같은 속성과 오퍼레이션을 가질 수 있다. 이것이 연관 클래스가 된다.

링크

객체가 클래스의 인스턴스인 것처럼 연관도 자신의 인스턴스를 가질 수 있다. 어떤 특정한 선수가 특정한 팀에 소속되어 있는 관계를 생각하면 이 때의 Plays on 연관 관계를 링크 (Link)라고 부른다. 링크는 두 객체(인스턴스)를 선으로 이어서 나타낸다.

링크는 연관의 인스턴스로서 클래스가 아닌 객체 사이를 연결한다. 예를 들어 위의 선수와 팀이 맺은 계약의 경우 선수라는 클래스의 인스턴스인 박지성과 팀이라는 클래스의 인스턴스인 맨유가 있을 때 박지성과 맨유의 계약이 계약이라는 연관클래스의 인스턴스인 링크가 된다.

다중성

다중성 (Multiplicity)이란 연관되어 있는 두 클래스 사이에서 한 클래스의 객체와 관계를 가질 수 있는 다른 클래스의 객체 개수이다. 예컨대 축구 팀은 11명의 선수로 구성되므로 팀의 입장에서 보면 11명의 선수와 연관되어 있는 것이다.

수식연관

일대다의 다중성을 가진 연관 관계에서는 한 객체가 특정한 객체를 가려내어야 하는 상황(이를 Lookup 이라고 한다)이 발생한다. 한쪽 클래스의 객체가 다른 쪽 클래스의 객체를 선택하여 연관 관계 내에서의 역할을 만족시켜야 할 때 첫째 클래스는 자신이 원하는 객체를 찾기 위해 특정한 속성에 의존할 수 밖에 없는데 대게 이 특정한 속성은 ID 번호 같은 식별자에 해당된다.

예를 들어 하나의 예약 리스트는 여러 건의 예약을 갖고 있는데 여러분이 호텔에 방을 예약할 때 호텔로부터 확인 번호나 이름 등을 받게 된다. 예약과 관련하여 문의를 하고자 한다면 예약 리스트에서 해당 예약 건을 찾을 수 있도록 확인 번호나 이름을 불러주어야만 한다

반사연관

클래스는 자신과 연관 관계를 가질 수도 이으며 이것을 반사연관 (Reflexive Association)이라 한다. 여러 가지 역할을 맡을 수 있는 객체를 가지고 있을 떄 이런 경우가 발생한다. 탑승자는 운전자도 될 수 있고 승객도 될 수 있다.

상속과 일반화

한 클래스(자식클래스 혹은 서브클래스)는 다른 클래스(부모클래스 혹은 슈퍼클래스)로부터 속성과 오퍼레이션을 물려받을 수 있다. 슈퍼 클래스는 서브 클래스보다 일반적인 특성을 가진다.

슈퍼클래스를 가지지 않는 클래스는 기본 클래스(Base Class) 또는 루트 클래스 (Root Class)라고 하며 서브 클래스를 가지지 않는 클래스는 리프 클래스 (Leaf Class)라고 한다.

클래스가 단 하나의 슈퍼클래스를 가지는 상속을 단일 상속 (Single Inheritance)라고 하며두 개 이상의 슈퍼클래스를 가지는 상속은 다중 상속 (Multiple Inheritance)라고 한다.

추상 클래스

객체를 제공하지 않는 클래스는 추상 클래스 (Abstract Class)라고 한다.

의존관계

한 클래스가 다른 클래스를 사용하는 경우 의존관계 (Dependency)라고 한다. 의존관계가 가장 흔하게 드러나는 예는 다른 클래스를 사용하는 오퍼레이션의 시그너처를 보일 때이다.

집합연관, 복합연관, 인터페이스 그리고 실체화

집합연관

하나의 클래스가 여러 개의 컴포넌트 클래스로 구성되어 있는 경우가 있다. 이러한 상황은 집합연관 (Aggregation)이라 불리는 특수한 관계이다

복합연관

복합체 (Composite)는 강한 집합연관에 의해 만들어진 클래스이다. 복합체에서 각 컴포턴트 클래스는 오직 하나의 전체 클래스에만 속할 수 있다.

인터페이스와 실체화

자동차와 TV는 인터페이스 (Interface)를 통해 행동을 수행하라는 메세지를 받는다. 인터페이스란 클래스의 일정한 행동(Behavior)을 나타내는 오퍼레이션의 집합으로써 다른 클래스에서 사용될 수 있다.

세탁기를 예를 들면 세탁기의 조절 손잡이가 세탁기의 인터페이스가 된다. 사용자는 세탁기를 돌리기 위해 세탁기의 회로를 뜯어낼 필요 없이 세탁기의 조절 손잡이만 조절하면 세탁기를 돌릴 수 있다.

세탁기의 행동 중 일부가 조절 손잡이의 행동을 실체화 (Realize) 한 것이라고 한다. 클래스와 인터페이스가 가지는 이러한 관계를 실체화(Realization) 관계라고 한다.

인터페이스는 속성을 가지지 않는다

가시성

인터페이스와 실체화에 대하여 뗄래야 뗄 수 없는 관계를 가진 것이 바로 가시성이라는 개념이다. 가시성 (Visibility)이란 속성과 오퍼레이션에 적용되는 것으로 해당 클래스(혹은 인터페이스)의 속성과 오퍼레이션을 들여다 볼 수 있는 범위를 말한다.

  • Public 속성과 오퍼레이션은 다른 클래스가 마음껏 사용할 수 있다.
  • Protected 속성과 오퍼레이션은 원래 클래스와 여기서 상속 받은 클래스만이 사용할 수 있다.
  • Private 속성과 오퍼레이션은 원래의 클래스만이 사용할 수 있다.

왜 가시성이 실체화와 밀접한 관계를 가지고 있을까? 인터페이스를 실체화 하기 위해서는 인터페이스 안에 설정된 오퍼레이션들이 모두 Public 가시성을 가지고 있어야 한다. Protected, Private로 막힌 오퍼레이션은 아무런 의미가 없다. 왜냐하면 인터페이스는 많은 클래스들에 의해 실체화되기 위한 용도로 고안되었기 때문이다.

스코프

속성과 오퍼레이션이 가지고 있는 또 하나의 특성으로써 스코프 (Scope)가 있다. 스코프에는 두 가지 종류가 있는데 인스턴스 스코프 (Instance Scope)에서는 각각의 인스턴스에 속한 속성과 오퍼레이션들이 각자의 값을 가지도록 되어있다. 클래스 스코프 (Classifier Scope)에서는 해당 클래스에 대해 유일한 속성값과 오퍼레이션값을 가진다.

[ssba]

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기