[S/W] UML Class Relationships

본 글에서는 UML Class Diagram에서 클래스 간 관계를 표현하는 주요 방식에 대해 설명한다. 아래에 결합도(의존 강도)가 낮은 순서대로 Class관계를 표현하였다.

use-a, has-a, is-a 관계로 묶어서 보면 더 잘 와 닿는다.

코드 예제는 C++로 작성하였다.


1. Dependency#

  • use-a 관계

  • 소유하지 않음 (== 멤버 변수로 쓰이지 않음)

  • example)

    class Person {
    	void Read(Book * book) {
    		//...
    	}
    };
    // Person ------> Book
    

2. Association#

  • has-a 관계

  • 가졌다고 보긴 어렵고, 참조 정도만 하는 것을 말함

  • 포인터 멤버변수를 갖고 있으나, 여기에 값이 들어올 수도 있고, 아닐 수도 있음.

  • 나중에 멤버 함수를 통해서 객체를 전달 받음.

  • 사람 has a 책 이라고 할 때, 사람이 죽어도 책이 죽지 않으므로 association으로 관계를 표현할 수 있음.

  • example)

    class Person {
    	Book *book;
    	Book *BuyBook(Book *book) {
    		this->book = book;
    	}
    };
    // Person → Book
    

3. Aggregation#

  • has-a 관계

  • Association과 완전히 같으나, 복수 관계를 표현한다고 생각하는게 편함. 즉, Association은 책을 1권, Aggregation은 책을 여러권 갖는 방식임.

  • example)

    class Person {
    	vector<Book*> books;
    	void AddBook(Book *book) {
    		books.emplace_back(book);
    	}
    };
    // Person ◇→ Book
    

4. Composition#

  • has-a 관계

  • Pointer변수(참조)가 아닌 일반 변수를 멤버 변수로 갖는다.

  • 생애주기를 함께한다! 지금까지 예제 든 것을 기반으로 말하면, 사람이 책을 갖고 있을때 사람이 죽으면 책도 소멸하는 경우를 말한다.

  • 사람이 죽을 때 책도 소멸한다는건 이상하므로 다른 예제를 생각해보자.

    class Heart {
    	void BeatFast() {
    		//...
    	}
    };
    class Person {
    	Heart heart;
    	void run() {
    		heart.BeatFast();
    	}
    };
    // Person ◆→ Heart
    // 사람이 죽으면, 사람이 갖고있던 Heart도 그 기능을 다 하는 것으로 보는게 일반적이므로
    // 두 클래스의 관계를 Composition으로 나타내는 것이 적절하다.
    // 참고로, Association, Aggreagation과 달리 Composition은 혼자서 단수도 되고, 복수도 된다.
    

5. Realization#

  • is-a 관계

  • 어떤 Class가 Interface를 실체화 시키는 관계를 표현한다.

  • example)

    class Person{
    	void UseTv() {
    		RemoteControl rc;
    		rc.TurnOnTv();
    		//...
    	}
    };
    
    #define interface struct
    interface RemoteControl{
    	virtual void TurnOnTv()=0;
    	virtual void TurnOffTv()=0;
    	virtual void ChannelUp()=0;
    	virtual void ChannelDown()=0;
    	virtual void VolumeUp()=0;
    	virtual void VolumeDown()=0;
    };
    
    class SamsungTvRemoteControl : public RemoteContorl{
    	void TurnOnTv() override {
    		//...
    	}
    	void TurnOffTv() override {
    		//...
    	}
    	void ChannelUp() override {
    		//...
    	}
    	void ChannelDown() override {
    		//...
    	}
    	void VolumeUp() override {
    		//...
    	}
    	void VolumeDown() override {
    		//...
    	}
    };
    
    // SamsungTvRemoteControl ----▷ RemoteControl
    

6. Generalization#

  • is-a 관계

  • 어떤 Class가 다른 Class를 상속받는 관계를 표현한다.

  • 자식클래스가 부모클래스를 Generalization 했다고 말한다.

  • 파생클래스가 기본클래스를 Generalization 했다고 말한다.

  • Derived Class가 Base Class를 Generalization 했다고 말한다.

  • example)

    class Car{
    	void Run() {
    		//...
    	}
    };
    
    class SuperCar: public Car{
    	void FastRun() {
    		//...
    	}
    };
    // SuperCar ─▷ Car