SW 설계에서 UML 을 공부하다보면 등장하는 5가지 Class 관계가 있다 (OOAP). 이 Class 관계도는 SW 를 설계할 때 어떤식으로 SW를 설계할지에 대해서 확실한 그림을 잡아주기 때문에 상당히 중요한 역할을 하고, 커뮤니케이션에서도 중요한 역할을 하는 것 같다. 개발 실무적인 영역으로만 학습을 많이 했다면 처음 들어보는 관계일 수도 있지만 절대 어려운 개념들은 아니니, 한 번 이해해보는 기회가 되면 좋을 것 같다.
이제 배울 내용은 SW를 구현하기 전 설계 단계에서 Class 간 관계를 설계해 놓을 때 많이 사용하고 표시해두는 관계이다. 실무적인 공부만 하다가 다음과 같은 정보를 많이 접하는 것 같았다.
Class 들이 서로 의존한다 == Class 코드 안에 다른 Class 가 등장하여 서로의 존재를 알고 있음
실무적으로는 위의 사실이 크게 문제가 되는 부분은 아니다. 하지만 설계 시점에서 저렇게만 정의하는 것은 설계단과 커뮤니케이션시 다소 문제가 될 수도 있는 부분이기 때문에 조금 더 정확히 알고 넘어가는게 좋다. 우선 간략하게 살펴보면 다음과 같다
1. Dependency - 잠깐 일하고 끝나는 사이 (구현 직전 단계까지 가야 정확히 나오는 관계이다)
2. Association - 설계시 가장 많이 사용하는 관계로, 일정 시간동안 같이 협력하는 사이. Association 에는 두가지 관계가 있다.
3. Shared Aggregation - Association 관계 중 첫번째. 만들어진 Object 를 사용하는 경우
4. Composition - Association 관계 중 두번째. 직접 타 Class 를 통해 Object 를 내부적으로 생성하여 사용하는 경우
5. Inheritance - Generalization 관계로, 부모 / 자식의 관계
그림에도 나와있듯이, 5번 관계로 갈수록 두 클래스는 강한 결합의 관계이며, 1번으로 갈수록 약한 결합의 관계라고 볼 수 있다. 또한, UML 중 하나인 Class Diagram 에서는 위 관계들을 표현하는 화살표가 다르다. 이제부터 하나씩 살펴보자.
Dependency
public class Group {
public void updateInfo(GroupInfo groupInfo){
String name = groupInfo.getName();
// ... GropuInfo 를 통해 추후 update 진행
}
}
위 예제에서는 Group Class 내의 updateInfo() 함수가 GroupInfo Object 를 변수로 받아서 getName()을 통해 내부적인 메세지를 전달한다. 중요한 점은 GroupInfo 가 수정된다면, Group Class 에 영향을 줄 수 있다는 점이다. 또한, updateInfo() 함수가 종료되면 Group 이 GroupInfo 를 parameter 로 받은 상태였기 때문에 함수 종료시 더 이상 GroupInfo 를 참조할 수 없다는 특징도 있다. 위와 같은 Class Diagram 으로 그려질 수 있고, 점선 화살표로 표현이 된다.
Association
사실 Association 관계는 대표적인 두 가지 관계 (Aggregation, Composition) 으로 대부분이 정의되기 때문에, 다른 상황에 대해 굳이 구체적으로 알아볼 필요는 없다고 생각한다. 그래도Association 관계에 있어서 다음 용어 및 상황들에 대해서 잠깐 알아보자.
1) Navigability
Association 관계에서 추가되는 표현중 Navigability 가 있다. 즉, A 가 B 에 대한 Navigability 를 가지고 있다고 한다면, A 클래스는 B 클래스의 존재를 알고 있어, B 클래스의 visible 한 변수와 함수들에 접근할 수 있다는 뜻이다.
위 관계처럼 화살표로 표현하는데, 위 그림처럼 양쪽다 화살표가 없다면 서로 Navigability 가 있다는 뜻이며, 한 쪽으로만 있으면 반대쪽은 Navigability 가 없다는 뜻이라고 한다. (1:N, N:1 매핑할 때 연관관계 매핑을 하냐마냐랑 비슷한 듯)
2) Association Class
Association class 란 서로의 관계를 각 클래스에 두기보단, 또 다른 Class 를 만들어 정의하는 방식을 말한다. 관계형 매핑을 해보신 분들은 N:N 관계를 만들 때 연결 객체를 두는 것과 똑같다고 생각하면 된다.
가령, Lecture 와 Student 와 같은 Class 들이 있다면, Lecture 에는 여러 Student 들이 있고, Student 는 여러 Lecture 을 들을 수 있다. 특정 Lecture Object 와 특정 Student Object 마다 [등록 시간, 확정 여부, 성적, 담당 조교, ...] 등의 내용을 가지고 있어야 하는데, 각각 Class 안에 모든 Object 들을 위해 이런 내용들을 담는 것은 불가능한 일이다. 따라서 다음과 같이 정의한다.
이걸 보고 흔하게 N:N Entity Table 이네 하고 넘어갈 수도 있다. 맞는 말이지만, 지금은 최대한 실무 영역에서 벗어나서 순수 OOP 언어적으로 생각하는게 좋다. 꼭 DB Table 과 매핑되는 Entity 가 아니라, 위와 같은 관계는 OOP 언어적으로 시작된 관계이며, 서로 unique 한 object 를 지칭해야 하기 때문에 Hash 값을 이용하는 방식 등을 사용하기도 한다.
3) Interface
우리 모두가 사랑하는 Interface 이다. 디자인 패턴의 핵심이 되는 이 관계는 위에서 말한 두가지 Association 중 하나가 아니지만, Association 관계에 포함시키기는 하는 것 같다 (Interface 는 근데 흔히 Class 간 관계는 아니라고 생각한다. 왜냐하면 Interface 는 클래스가 아니기 때문이다). Interface 는 다음과 같은 하얀 점선 화살표로 표현한다.
Association 1 - Shared Aggregation (Aggregation)
Shared Aggregation 은 A 클래스가 B를 가지고 있을 때, 약한 소유 관계를 가지고 있는 관계이다. A가 B를 Shared Aggregation 관계로 가지고 있다고 하며, 다음과 같이 예시를 들 수 있다.
public GroupMember {
private Group group;
private Member member;
public GroupMember(Group group, Member member){
this.group = group;
this.member = member;
}
// ...
}
이와 같은 관계일 경우 GroupMember 에는 특정 Group Object 와 특정 Member Object 를 중심으로 형성이 되기 때문에, GroupMember 가 각각 Group 과 Member 를 Shared Aggregation 관계로 가지고 있는 것이다.
이 때, GroupMember Object 가 사라진다고 해서 (Member가 Group을 탈퇴함), 기존 Group 과 기존 Member 가 없어지지 않는다. 이런 소유 관계를 Shared Aggregation 관계라고 한다.
Association 2 - Composition
Composition 관계는 A 클래스가 B를 가지고 있을 때, 강한 소유 관계를 가지고 있는 관계이며, A Object 가 없어진다면 B Object 도 같이 삭제가 된다. 만약 A가 B를 Composition 관계로 가지고 있다고 하며, 다음과 같이 예시를 들 수 있다.
public Building {
private Office office;
public Building(Office office){
this.office = new Office(~~, ~~, ~~, ...);
// ...
}
// ...
}
Building 이 삭제된다면 당연히 Building 안에 있던 사무실 모두 삭제가 되어야 한다. 이런 논리 관계를 위와 같이 표현할 수 있으며, Building 이 Office 를 Composition 관계로 가지고 있는 것이다.
Inheritance (Generalization)
지금까지 배웠던 관계 중 가장 강력한 관계를 가지고 있는 관계는 Inheritace 관계이다. Class Diagram 에서는 Interface 화살표에서 점선이 아닌 실선 흰색 화살표로 표현한다.
위와 같이 상속 관계로 표현되며, 부모의 public, protected 한 정보들을 모두 access 및 override 할 수 있다. 또한, 부모 관계가 가지고 있는 모든 연관 관계를 그대로 상속 받을 수 있다. 이런 관계를 Class Diagram 에서는 굳이 표현하진 않으며, 당연하다고 보는 영역이다.
참고로 Java 에서는 Multiple Inheritance 관계는 금지하고 있다. C++ 에서는 아니긴 하지만, 일반적으로 Inheritance 관계는 한가지로만 사용하는 것을 권장한다. (Inheritance 는 일반적으로 [종류] 라고 보는데, [종류]가 여러개로 나뉘면 좋은 설계가 아니다)
1) Abstract Class
Abstract Class 는 구체적인 Instance 를 생성하는 것을 금지하며, 오직 상속 관계만을 정의하기 위한 class 이다. Abstract Class 는 Class Diagram 에서 {abstract} 라는 표현을 적어주며, 다음과 같이 보여진다.
이 관계에서 Person person = new Person(); 과 같이 Person 에 대한 Instance 를 생성하는 것은 문법적으로 금지되며, 공통적인 속성들만 자식들이 상속받게 되며, 각자의 고유 성질들을 정의할 수 있는 관계가 된다.
* Person person = new Person(); (X)
* Person man = new Man(); (O) // 하지만 이럴 경우 Person 의 Object 이기 때문에, Man 만의 변수 / 함수는 사용할 수 없음
* Man man = new Man(); (O) // 이럴 경우 Man Object로서 활용할 수 있고, Person의 모든 관계들과도 상호작용이 가능
* Person woman = new Woman(); (O)
위와 같이 전체적인 Abstract Class 의 관계를 기준으로, 또 다른 일반 Inheritance 관계까지 상관 관계를 정의하는 상황을 만들 수 있다.
정리하며
언제든지 SW 를 만들기 전에는 설계를 간단하게라도 해보는 것이 정말 너무 중요하다고 느껴진다. 물론 위 관계를 처음부터 완벽하게 그리는건 불가능하다.
No silver bullet in SW Engineering
SW 공학에서 완벽한 설계란 없다고 한다. 그 때 상황에 맞게, 그 때에 최적화된 설계를 하고, 전체적인 SW 의 완성도가 진행됨에 따라서 지속적으로 같이 완성되어 나가는게 맞는 것이다. 어렵고 귀찮다고만 생각하지말고 설계의 중요성을 인식한 만큼 실무나 프로젝트에 적용해 나가는 방향으로 해보자!
* 참고
많이들 스프링을 통해 Java 를 접했을텐데, 그 때 많이 접한 "의존성" 이란 말은, 위의 모든 관계를 다 포함해서 말했던 것이라고 보면 될 것 같다. 하지만 A 클래스가 B 클래스의 존재를 안다고 하는 상황이, 정말 여러가지 상황이 있기 때문에 위와 같은 관계들을 통해서 "의존한다" 라고 보면 되는 것 같다.
@Service
@RequiredArgsConstructor
public class HelloService {
private final HelloRepository helloRepository;
// ...
}
예를 들어, @RequiredArgsConstructor 는 위 Shared Aggregation 관계인 것이다. 생성자를 만들어주고, private 하고 생성 시점 이후로 바뀌지 않는 final 한 Object 를 주입시켜주는 것이기 때문이다. 다만, Spring Container 에서 찾아와서 넣어준다는 것은 여기서 생각할 필요가 없는 것이다. 그 Object 들 역시 모두 하나의 메모리 주소를 가지고 있는 Object 들이기 때문이다.
Spring 에서 Service 영역은 순수 Java 개발 영역이며, Spring 에서 관여하지 않는 유일한 영역이다. Service Layer 야 말로 개발자의 SW 설계 및 객체지향적 사고 능력을 발휘하는 Layer 가 아닐까?
* 출처)
건국대학교 유준범 교수님 OOP / UML / OOAD 수업
'SW 설계 > UML' 카테고리의 다른 글
[UML] Statechart Diagram 에 대해 알아보자 (0) | 2023.10.09 |
---|---|
[UML] Sequence Diagram 에 대해 알아보자 (0) | 2023.10.08 |