[디딤돌 C++] 70. 최종 실습 – 설계1(클래스 다이어그램)

설계 단계에서는 프로그램에 정의할 형식을 정하고 이들 사이에 관계를 정의하는 것과 유즈케이스 별로 수행 흐름을 정의하는 작업이 있습니다.

프로그램에 정의할 형식을 정하고 이들 사이에 관계를 정의한 것은 클래스 다이어그램으로 표현합니다.

유즈케이스 별로 수행 흐름을 정의하는 것은 여러 가지 다이어그램으로 표현할 수 있는데 여기에서는 시퀀스 다이어그램으로 작성할게요.

먼저 프로그램에 정의할 형식을 정하고 이들 사이에 관계를 정의합시다.

제일 먼저 이 에이치 나라와 학생 공장이 있죠.

그리고 학교, 주거지, 다운타운이 있죠. 그런데 이 세 개의 형식은 학생이 올 수 있고 초점을 받아 사용자와 상호작용을 수행하는 등의 공통점이 있습니다. 논리적으로 보았을 때도 “학교, 주거지, 다운타운은 장소이다.”로 표현할 수가 있으니 일반화 관계로 표현합시다.

그리고 학생이 있으며 학생의 종류에는 마법학생, 운동학생, 학사학생이 있으니 마찬가지로 일반화 관계로 표현합시다.

그런데 학교, 주거지, 다운타운에서는 학생에게 약속한 기능을 제외한 나머지 기능을 호출하지 말아야 합니다. 각 형식 별로 멤버 메서드의 가시성을 다르게 접근 지정하는 문법은 없습니다. 이를 해결하기 위해 무엇이 필요할까요?

이 때 인터페이스로 기능 구현을 약속하여 각 장소에서는 학생 개체를 인터페이스 형식으로 접근하여 사용하면 문제를 해결할 수 있습니다. 그런데 학생 종류에 관계없이 “공부하다”, “자습하다”, “휴식하다”, “잠자다”, “노래하다”, “음료마시다”는 모두 구현해야 하는 기능인데 학생 형식으로 이미 접근할 수 있으니 인터페이스로는 요구 조건을 만족할 수 없습니다.

이름과 주민번호를 멤버로 갖는 사람 클래스를 정의하고 이를 기반으로 학생 클래스를 정의합시다. 학교에서 할 수 있는 행위를 IStudy 인터페이스로 정의하고 학생 클래스는 이를 기반으로 정의합시다. 주거지에서 할 수 있는 행위를 IRelax 인터페이스로 정의하고 학생 클래스는 이를 기반으로 정의합시다. 다운타운에서 할 수 있는 행위를 IPlay 인터페이스로 정의하고 학생 클래스는 이를 기반으로 정의합시다.

10분 이상 고민해도 이해할 수 없다면 이를 이해하기 위해 필요한 기반 지식이 부족한 것일 수 있습니다. 무엇이 부족한 것인지 파악할 수 없다면 일단 마킹을 해 두고 구체적으로 구현하는 부분과 함께 살펴보세요. 물론 어느 부분이 부족한 것인지 파악할 수 있다면 먼저 그 부분을 학습한 후에 다시 보시기 바랍니다. 실제 학습하다보면 이와 같은 현상은 자주 발생합니다. 특히 어느 부분이 부족한 것인지 파악할 수 없을 때가 훨씬 많다는 것이 학습을 어렵게 하지요.

이 부분을 이해하기 위해서는 상속과 다형성에 관한 전반적인 지식이 필요합니다. 그리고 이러한 지식이 갖춰져 있다고 생각하는 이들도 충분한 경험이 없다면 이처럼 설계하는 것을 쉽게 이해하는 것은 어려울 수 있습니다.

이제 또 다른 산을 넘어가 봅시다. 시나리오를 보면 이에이치 나라에서 각 장소로 학생을 보낼 수 있고 각 장소에서는 학생을 이에이치 나라로 복귀할 수 있습니다. 그런데 이를 표현하기 위해서는 이에이치 나라는 장소에게 명령을 내릴 수 있어야 하고 각 장소도 이에이치 나라에 명령을 내릴 수 있어야 합니다. 연관관계가 발생하는 것이죠. 이는 프로그램의 구조를 취약하게 만듭니다.

이를 해결하기 위해 여기에서는 다시 인터페이스를 정의하여 사용할게요. 장소에서는 특정 학생을 복귀할 수 있다는 인터페이스 형식을 정의하고 생성자에서 이를 입력 인자로 받습니다. 이에이치 나라는 인터페이스를 기반으로 약속한 기능을 구체적으로 정의합니다. 그리고 장소를 생성할 때 자신을 입력 인자로 전달합니다.

이처럼 구현하면 이에이치 나라는 장소와 직접 연관 관계로 변합니다. 그리고 장소는 인터페이스와 직접 연관 관계이며 이에이치 나라는 인터페이스와 실현 관계입니다.

이제 나머지 관계들을 결정합시다. 이에이치 나라는 학생 공장에 주문을 할 수 있으므로 직접 연관 관계에 있습니다. 그리고 학생 공장은 학생을 생성하는 역할을 담당하므로 의존 관계에 있습니다. 그리고 이에이치 나라는 주문한 학생을 보관할 수 있어야 하므로 집합 관계에 있습니다.

장소는 학생이 아닌 학생의 기반 형식인 사람을 보관하고 있어야 합니다. 학생을 보관하게 하는 것은 요구 조건에 약속한 행위 외에 다른 행위를 명령할 수 없다는 조건을 위배합니다. 그리고 학교는 IStudy, 주거지는 IRelax, 다운타운은 IPlay 형식에 명령을 내릴 수 있으니 직접 연관 관계로 표시합니다.

그리고 학교는 학사 학생이 도서관으로 갔을 때 독서도 시킬 수 있어야 하며 주거지는 마법 학생이 거실에 갔을 때 여행을 보낼 수 있어야 하며 다운타운은 학사 학생이 노래방에 갔을 때 춤을 추게 해야 합니다. 이를 위해 직접 연관 관계를 추가로 표시하세요.

이를 한꺼번에 표현하면 다음과 같습니다.

최종 실습을 이와 같은 프로그램과 이러한 방법으로 하는 이유는 여러분께서 C++문법을 학생하는 것에 그치지 말고 소프트웨어 설계에도 관심을 가졌으면 하는 바램에서입니다. 소프트웨어 설계 패턴에 관한 다양한 레퍼런스를 참고하여 설계에도 관심을 가져야 보다 나은 OOP를 추가할 수 있을 것입니다. 참고로 설계를 영어로 번역하면 디자인입니다. 디자인 패턴이라는 이름으로 소개하는 책은 소프트웨어 설계 패턴에 관한 책이라고 생각할 수 있습니다. 간혹 온라인/오프라인 서점에서 그래픽 디자인 파트로 분류하고 있는 책들도 확인해 보시면 소프트웨어 설계에 관한 책들도 많습니다.

여러분께서는 이번 실습에서 앞에서 다룬 내용을 정리하는 것과 개발 공정에 따라 프로그래밍하는 경험을 쌓는 것에 초점을 맞추기 바랍니다.