📚 학습 개요
💡 《객체지향의 사실과 오해》의 내용을 기반으로 도메인을 설계한다. 구체적인 방안은 다음과 같다.
- 장기 도메인을 구성하는 개념들에 대해 떠올려 간단한 도메인 모델 만들기
- 유스케이스 하나를 뽑는다.
- 해당 유스케이스에 대해 기존 도메인 모델을 참고하여 떠올렸던 개념을 기반으로 협력을 설계한다.
- 설계한 협력을 기반으로 도메인 모델을 업데이트 한다.
- 다른 유스케이스에 대해서도 2~3번을 반복한다.
🎯 학습목표
- 도메인의 핵심 개념과 관계를 식별하여 의미 있는 객체와 책임 중심의 도메인 모델로 구조화할 수 있다.
- 유스케이스를 절차가 아닌 객체 간 협력 과정으로 해석하고 표현할 수 있다.
- 객체 간 메시지를 정의하고, 이를 기반으로 적절한 책임을 분배할 수 있다.
📄 산출물
- 도메인 모델
- 유스케이스에 대한 객체 간 협력 다이어그램
✅ 장기 도메인 이해하기
설계에 앞서 설계하고자 하는 도메인에 대해 공부해보자.
참고: 장기 - 위키백과
🧩 1. 장기판 구성

- 판: 9×10 줄 (가로 9칸, 세로 10칸)
- 기물의 초기 위치는 사진과 같으며, 마(馬)와 상(象)의 경우 위치를 변경할 수 있다
- 궁성: 궁(宮) 및 사(士)가 위치하는 X자 형태의 공간
♟️ 2. 기물 종류와 행마법
참고: 장기의 행마법

🔁 3. 기본 규칙
- 항상 초나라(파란색)이 먼저 두고, 번갈아 한 번씩 이동
- 상대 말을 있는 칸으로 이동하면 잡기
⚡ 4. 특수 규칙
🔥 빅장
- 두 왕이 같은 줄에서 서로 마주보면 안 됨
- 반드시 사이에 다른 말이 있어야 함
🧠 장군
- 상대 왕이 잡힐 위험에 놓인 상태
- 반드시 피해야 함 (막거나 이동)
🤝 멍군
- 장군을 당했을 때 대응하는 상황
✋ 외통수
- 장군을 했는데 상대가 멍군을 할 수 없는 경우
🎯 5. 승리 조건
대국 방식은 크게 두 가지, 승부제 방식과 점수제 방식으로 나뉜다.
승부제 방식
- 상대 왕(궁)을 잡거나 외통수면 승리
- 빅장 또는 반복수일 경우, 비긴다.
점수제 방식
- 기본적으로 승부제 방식의 승리조건은 유지하되 점수가 추가된 방식이다.
- 기물별 점수표:
| 기물 | 차(車) | 포(包) | 마(馬) | 상(象) | 사(士) | 졸/병(兵/卒) | 후수(後手) |
| 점수 | 13 | 7 | 5 | 3 | 3 | 2 | 후수 1.5점 |
후수의 경우 1.5점이 더 주어지기 때문에 초는 72점, 한은 73.5점으로 시작함
✅ 장기 도메인 모델 설계하기
1️⃣ 장기 도메인을 구성하는 개념 떠올리기
도메인 이야기를 읽고 눈에 보이는 큰 개념들 위주로 떠올려본다. 너무 구체적으로 하려고 하지 않는다.
- 플레이어
- 장기판
- 기물

🔄 사이클1:
2️⃣ 유스케이스 뽑기
유스케이스명: 장기 게임 시작
일차 액터: 플레이어
주요 성공 시나리오:
1. 시스템은 두 명의 플레이어에게 나라를 부여한다.(플레이어1-초, 플레이어2-한)
2. 사용자는 마/상의 위치를 설정한다.
3. 시스템은 장기판의 기물을 초기화한다.
3️⃣ 협력 설계하기

- 가장 먼저 `장기게임`이 외부로부터 플레이어들의 마/상 위치를 전달받아 협력을 시작한다. 즉, `장기게임`은 이 게임 자체를 초기화하는 역할을 맡는다.
- `장기게임`은 나라를 부여받은 두 `플레이어`를 생성한다.
- `장기게임`은 장기판을 초기화하는 방법을 모르기 때문에 `장기판`에게 장기판을 생성하라는 메시지를 플레이어들의 마/상 위치와 함께 전달한다.
- `장기판`은 `기물`들을 생성한다.
- `장기판`은 생성한 `기물`들을 적절한 위치에 배치한다.
4️⃣ 도메인 모델 업데이트 하기

변경사항:
- (추가)장기게임: 게임을 초기화하고 규칙을 수행하는 주체
🔄 사이클2:
2️⃣ 유스케이스 뽑기
유스케이스명: 장기 기물 움직이기
일차 액터: 플레이어
주요 성공 시나리오:
1. 사용자는 움직이고자 하는 기물을 선택한다.
2. 시스템은 해당 기물이 움직일 수 있는 지점을 제공한다.
3. 사용자는 제공받은 지점 중 한 곳을 선택한다.
4. 시스템은 기물을 해당 지점으로 이동시킨다.
3️⃣ 협력 설계하기
움직일 수 있는 지점 제공

- 가장 먼저 `장기게임`이 외부로부터 기물의 위치를 전달받아 협력을 시작한다.
- `장기게임`은 스스로 기물이 움직일 수 있는 지점을 판단하기 어렵기에 `장기판`에게 움직일 수 있는 지점을 제공하라는 메시지를 기물의 위치, 현재 순서와 함께 전달한다.
- `장기판`은 먼저 해당 위치에 현재 순서의 기물이 실제로 있는지 검증한다.
- `장기판`은 기물이 움직이는 방법은 모르기 때문에 `기물`에게 ‘움직일 수 있는 지점을 제공하라’는 메시지를 선택된 기물의 위치, 장기판과 함께 전달한다.
- `기물`은 스스로 움직일 수 있는 지점을 계산한 뒤, 지점 목록을 `장기판`에게 넘겨준다.
- `장기판`은 `기물`에게 받은 지점 목록을 그대로 `장기게임`에게 돌려준다.
기물 이동시키기

- 가장 먼저 `장기게임`이 외부로부터 기물의 현재 위치, 이동 할 위치를 전달 받아 협력을 시작한다.
- `장기게임`은 기물을 움직이게 할 능력이 없기 때문에 `장기판`에게 ‘기물을 움직이라’는 메시지를 기물의 현재 위치, 이동 할 위치와 함께 전달한다.
- `장기판`은 먼저 해당 위치에 현재 순서의 기물이 실제로 있는지 검증한다.
- `장기판`은 기물이 움직이는 방법은 모르기 때문에 `기물`에게 ‘움직일 수 있는가?’라는 메시지를 선택된 기물의 위치, 장기판과 함께 전달한다.
- `기물`은 움직일 수 있는지 체크하고 그 여부를 `장기판`에게 넘겨준다.
- 가능하다면 `장기판`은 해당 기물을 이동시킨다.
4️⃣ 도메인 모델 업데이트 하기

변경사항:
- (제거)플레이어: 실질적으로 플레이어가 현재 협력에서 맡을 수 있는 책임이 없다고 생각했다. 최초로 플레이어를 생각했던 이유는 누가 둬야할 차례인지 알기 위함이었는데, 이 경우 `장기 게임`에서 내부적으로 처리할 수 있기 때문에 굳이 플레이어를 만들 필요가 없어졌다.
↩️ 도메인 모델 변경으로 인한 이전 협력 수정
이전에 설계한 ‘장기 게임 시작’ 협력에서는 `플레이어`가 존재했었기 때문에 해당 부분을 제거해야한다.
대신 해당 부분을 ‘현재 순서’라는 내부 상태로 관리한다.

🤔 고민했던 부분들
1️⃣ 메시지를 어디까지 추상화할것인가?
기물이 움직일 수 있는 지점을 제공하려면 먼저 해당 기물이 실제로 존재하고, 현재 순서인 쪽의 기물이 맞는지를 체크해야 한다.
🔷 초안:
처음에는 아래와 같이 장기게임이 장기판에게 먼저 `‘기물을 검증하라’`는 메시지를 먼저 보낸 다음, `‘움직일 수 있는 지점을 제공하라’`는 메시지를 보내도록 설계했다.

🔷 변경:
하지만 이렇게 했더니 너무 메시지가 추상적이지 못하다는 생각이 들었다.
‘객체지향 사실과 오해’에서는 메시지가 추상적이어야 그 메시지를 받을 객체가 자율적으로 메시지를 처리할 수 있게 된다고 했다.
따라서 아래와 같이 `‘기물을 검증하라’`는 메시지를 `‘움직일 수 있는 지점을 제공하라’`는 메시지 안에 내포시켰다.
즉, 쉽게 말해 장기판이 움직일 수 있는 지점을 제공하는 행동을 할 때, 기물을 검증하는 행동을 장기판 내부에서 처리하겠다는 것이다.

이렇게 하면, 메시지의 구조가 깔끔해지고, 이전에는 두번에 나눠서 보냈던 메시지를 하나로 바꿨기 때문에 장기판의 응집도도 높아진다.
다만, 이렇게되면 기물을 검증하는 로직은 내부에 숨겨지기 때문에 직접적인 테스트가 어려워진다는 단점은 있다. 하지만 현재로서는 구조적인 안정성을 조금 더 우선시해야 한다고 생각하여 이 구조대로 가기로 결정하였다.
2️⃣ 왜 자꾸 코드를 떠올릴까?
객체지향 설계를 시작할 때는 결과물인 코드를 생각하지 말고, 최대한 객체 간의 협력에 집중해야 하는데 나도 모르게 자꾸 코드를 떠올렸던 것 같다. 그러다 보니 협력이 아니라 개별적인 객체에 집중하게 되고, 책임에 대한 분배가 애매해지는 경우가 많았다.
이러는 이유에는 장기 도메인 자체에 대한 이해가 부족한 탓도 있는 것 같다. 이번에 장기를 처음 다루다 보니 혹시 놓친 부분이 있지는 않을지 계속 걱정하게 되었고, 다양한 경우를 한 번에 모두 반영하려다 보니 메시지를 충분히 추상화하지 못한 채 설계하는 일이 많았다.
또한 객체지향에 대한 이해가 아직 부족한 점도 영향을 준 것 같다. 이 책이 객체지향 설계의 방향성을 제시해주는 것은 분명하지만, 실제로 적용해볼 수 있는 구체적인 예시는 다소 부족하게 느껴졌다. 그래서 이론을 이해하는 것과 이를 실제 설계에 녹여내는 것 사이에 간극이 존재한다는 점을 체감하게 되었고, 결국 이를 극복하기 위해서는 다양한 사례를 직접 설계해보며 경험을 쌓는 과정이 필요하다는 생각이 들었다.
'우테코 8기 > 본과정 탐구 일지' 카테고리의 다른 글
| [레벨1 블랙잭] Service 클래스에 대한 고찰 (0) | 2026.03.14 |
|---|---|
| [레벨1 블랙잭] 딜러와 플레이어의 관계 (i.e. 상속을 잘 쓰려면?) (0) | 2026.03.14 |