디자인 패턴을 공부하기 위해서는 클래스와의 관계를 파악하는 것이 중요하다. 그리고 클래스와의 관계를 파악할 때는 개인적으로 UML을 그려보는 것이 가장 좋다고 생각한다. 그리고 UML을 공부하다보면 항상 relationship의 개념이 모호할 때가 많다. 오늘은 그 모호한 개념들을 좀 더 확실하게 정리해보고자 UML의 대표적인 relationship에 대해 포스팅해보려 한다.
우아한 객체 지향 중 클래스 의존성 종류에 대한 조영호 님의 설명 👍
우아한 객체 지향 영상에서 조영호님이 쉽고 명확하게 설명해주셔서 감명받고 기존에 클래스간의 관계에 대해 정리해놓은 이 글을 수정하기로 했다.
Association (A "has a" B) : 연관관계
보통 Association 관계에서 B는 A의 field에서 attribute로 존재한다. 즉, A는 B를 가지고 있다. 아래 코드에서는 A 클래스가 B 타입 변수를 가지는 Association 관계이다. 관계가 단방향일 수도 있고 양방향일 수도 있는데, 아래 코드만을 봤을 때는 단방향 관계이다. A는 B의 존재를 아는 반면, B은 A의 존재를 모른다. (반면, 학생과 제자처럼 서로의 존재를 인지하는 경우에는 양방향 관계이다.)
class A {
private B b;
...
}
Dependency(A uses/depends on B ) : 의존 관계
아래 코드에서 A 클래스는 B 클래스를 사용하는 의존적인 관계이다. 이처럼 A의 메소드 파라미터로 혹은 리턴 타입으로 B를 사용하는 경우에는 A가 B에 의존적인 경우이다. 단, 영속적인 관계가 아니기 때문에 A가 사라진다 해서 B가 함께 수명이 끝나는 것은 아니다.
class A {
public void method(B b){ return new B(); }
...
}
❓Association (연관 관계) VS Dependency (의존 관계)
연관관계는 A와 B의 관계가 컴파일 타임에 결정된다. 때문에, A에 영속적으로 영구적으로 B로 가는 경로가 존재한다.
반면 의존관계는 A와 B의 관계가 런타임에 결정된다. 즉, 협력을 하는 특정 시점에 일시적으로 관계를 맺고 끝나는 관계다.
Inheritance : 상속 관계
말 그대로 클래스 B를 클래스 A가 상속받을 때 상속 관계가 성립된다.
class A extends B { ... }
Realization : 실체화 관계
B 인터페이스를 A 클래스에서 구체화할 때 실체화 관계가 성립된다.
class A implements B { ... }
❓Inheritance (상속 관계) VS Realization (실체화 관계)
상속관계의 경우 B 클래스의 구현이 바뀌면 이를 상속받은 A 클래스에도 영향을 주게 된다.
반면, 실체화 관계의 경우 구현이 B 인터페이스가 바뀌더라도 영향을 주지 않는다 (오버라이드한 메소드의 시그니처가 바뀔 때는 영향을 줄 수 있긴 하지만 상속 관계에 비해서는 파급 효과가 적다).
Aggregation (A "owns a" B)
A가 B를 소유하고 있지만 반드시 A만 소유하고 있어야하는 것은 아니다. 아래 코드를 보면 Room이 현재 Wall을 가지고 있긴 하지만 이 Wall들은 다른 Room에서도 사용할 수 있다. 그렇기 때문에 현재 Room object의 생명이 다하더라도 Wall은 없어지지 않은 채로 존재한다. 즉, 라이프 타임이 독립적이다.
class Room{
protected Wall walls[] = new Walls[4];
public Room(Wall north, Wall south, Wall east, Wall west){ ... }
...
}
빈 다이아 화살표로 표기
Composition (A is "part of" B)
가장 결속력이 강한 관계이다. A와 B의 생명주기가 같아서 A가 B 인스턴스의 생성과 파괴 모두를 담당한다. 그리고 B는 A 이외의 다른 클래스에는 속해있을 수 없다. 아래 코드를 보면 Wheel 타입 인스턴스는 Car의 생성과 동시에 만들어지고 Car에 완전히 종속되어있기 때문에 car의 생명이 다하면 함께 gc에 의해 사라진다. 즉, 라이프 타임에 의존적이다.
class Car{
wheel[] wheels;
public Car(){
wheels = new Wheel[2];
wheels[0] = new Wheel();
wheels[1] = new Wheel();
}
}
검은색 다이아 화살표로 표기
소프트웨어 엔지니어링 수업에서 프로젝트를 진행하기 전 SDD(Software Design Description)을 작성할 때 UML도 첨부해야했기 때문에 자주 접해보긴 했지만, 되돌아보면 Dependency, Association, Aggregation, 그리고 Composition 관계에 대해 충분히 이해하지 못한 채로 구글링으로 그때그때 찾아보았던 기억이 많다. 그래서 더욱 마음 한 구석에 무거운 짐처럼 남아있었는데 오늘 좀 더 명확하게 정리가 된 것같.. 지만 뭔가 아직도 충분하지 않은 느낌.
이와 관련된 책이 있다면 찾아서 읽어보고싶다.
[참조]
answer for the question sample java code needed for UML class associations