전체 보기
🪐

스토리텔링식으로 객체지향적인 설계 쉽게 따라해보기 (with [책] 객체 지향의 사실과 오해)

작성일자
2023/11/03
태그
JAVA
프로젝트
PreCourse
책 종류
1 more property

객체지향적으로 설계하는 법을 모르겠다 하시는 분을 위한 쉽게 따라해볼만한 꿀꿀팁

안녕하세요 이번 백엔드 6기 프리코스에 참여한 추서연입니다.
객체지향 알긴 아는데 어떻게 해야 미션에서 적용할 수 있는지 아직 감이 안오신 분들도 있을 거 같아요.
그런 분들을 위해 쉽게 따라해볼 수 있는 방법 하나를 추천드리고자 합니다!
저는 1주차가 끝나고서 절차지향적으로 코드를 짰단 피드백을 받았었는데요.
2주차에선 한 책을 보고 예제를 똑같이 미션에 적용해보며 객체지향적인 설계에 대해 조금씩 감을 잡아갈 수 있었습니다.
이 방법이 정답이란 건 아니지만, 가이드가 될 수 있으리라 기대합니다.
제가 사용한 책은 [객체 지향의 사실과 오해]라는 책입니다.
방식은 미션에 대해 스토리텔링식으로 이야기를 짜보고, 이를 협력/책임/역할로 나눠보는 것입니다.
책에 좋은 예제가 있어 이와 비슷하게 구성하다보면 본인만의 설계를 짤 수 있을 것입니다.
또, 이야기 구성하는 게 생각보다 재밌습니다 ㅎㅎ
실제로 제가 2주차 미션에 적용했던 과정을 아래 나열하겠습니다.

1. 책 속 예제

이야기 : 하트 왕의 파이를 도둑 맞은 사건에 대해 모자장수가 증언함
재판장엔 하트 왕, 하얀 토끼, 모자 장수가 있었음
하트 왕이 “첫 번째 목격자를 불러라” 라고 명령함
하얀 토끼가 “목격자인 모자 장수 나와라”라고 외침
모자 장수가 증언대에 섬
하트 왕이 “증언하라”라고 명령함
모자 장수가 증언을 함
협력 : 요청과 응답
누군가가 왕에게 재판을 요청함으로써 재판이 시작됨
왕이 하얀 토끼에게 증인을 부를 것을 요청함
왕의 요청을 받은 토끼는 모자 장수에게 증인석으로 입장할 것을 요청함
모자 장수는 증인석에 입장함으로써 토끼의 요청에 응답함
모자 장수의 입장은 왕이 토끼에게 요청했던 증인 호출에 대한 응답이기도 함
왕이 모자 장수에게 증언할 것을 요청함
모자 장수는 증언함으로써 왕의 요청에 응답함
책임 : 하는 것과 아는 것
하는 것 : 하얀 토끼에게 목격자 불러오도록 요청, 모자 장수에게 증언하라 요청
하얀 토끼
하는 것 : 모자 장수가 증인석에 입장하도록 요청
아는 것 : 목격자가 모자 장수라는 사실
모자 장수
하는 것 : 스스로 증인석에 입장(생성)
아는 것 : 증언할 내용(자신이 알고 있는 사실을 증언해야 할 책임)
역할 : 책임의 집합 (재사용성)
왕 → 판사
모자 장수 → 증인

2. 예제를 미션에 적용

이야기 : 자동차들이 경주를 함
게임장에 자동차들, 자동차 매니저, 진행자, 심판, 서기가 있음
진행자가 “자동차들 불러와라”라고 외침
매니저가 “빨간 자동차, 파란 자동차 나와라”라고 외침
빨간 자동차와 파란 자동차가 스타트 라인으로 나옴
진행자가 "서기야 이동 횟수 기록해라"라고 외침
서기가 초기 이동 횟수를 기록함
아래를 반복함
진행자가 “자동차들 출발!”이라고 명령함
매니저가 “빨간 자동차, 파란 자동차 출발!”이라고 외침
빨간 자동차와 파란 자동차가 이동함
진행자가 “자동차들 현재 위치를 말해라”라고 명령함
매너지가 자동자들 주행거리를 보고 “빨간 자동차 3m, 파란 자동차 1m 지점!”이라고 외침
진행자가 "서기야 이동 횟수 남았니?"라고 물음
서기가 남은 이동 횟수 없다고 답하면 반복 종료함
진행자가 심판한테 “우승자는 누구?”라고 물음
심판이 “우승자는~ 빨간자동차!”라고 답함
협력 : 요청과 응답
누군가가 진행자에게 경주를 요청함으로써 경주가 시작됨
진행자는 자동차들이 스타트 라인에 설 것을 요청함
진행자의 요청을 받은 매니저는 빨간 자동차와 파란 자동차가 스타트 라인에 설 것을 요청함
빨간 자동차와 파란 자동차는 스타트 라인에 섬으로써 매니저와 진행자의 요청에 응답함
진행자가 서기한테 이동 횟수를 기록할 것을 요청함
서기가 초기 이동 횟수 기록함으로써 진행자의 요청에 응답함
아래를 반복함
진행자가 자동차들에게 이동하라 요청함
진행자의 요청을 받은 매니저가 빨간 자동차와 파란 자동차한테 이동하라 요청함
자동차들이 이동함으로써 매니저와 진행자의 요청에 응답함
진행자가 자동차 매니저한테 자동차들 주행 거리에 기반한 현재 위치 말하라고 요청함
자동차 매니저가 자동차들의 주행 거리에 기반한 현재 위치를 답함으로써 진행자의 요청에 응답함
진행자가 서기한테 남은 이동 횟수 있냐고 물어봄
서기가 남은 이동 횟수 없다고 답하면 반복 종료함
진행자가 심판한테 우승자를 답할 것을 요청함
심판이 우승자를 답함으로써 진행자의 요청에 응답함
책임 : 하는 것과 아는 것
진행자
하는 것 :
매니저한테 자동차들 불러오도록 요청, 매니저한테 자동차들 이동하도록 요청
자동차 매니저에게 자동차들 현재 위치 답하도록 요청, 심판에게 우승자 답하도록 요청
심판
하는 것 : 우승자 판독
아는 것 : 최종 결과
서기
하는 것 : 이동 가능 여부 결정
아는 것 : 남은 이동 시도 횟수
(자동차) 매니저
하는 것 : 자동차가 스타트라인에 입장하도록 요청, 자동차가 이동하도록 요청, 자동차들 현재 주행거리 관리
아는 것 : 게임에 참여할 자동차들, 자동차들 주행거리
자동차
하는 것 : 스스로 스타트라인에 입장(생성), 이동
아는 것 : 이동할 수 있는지 없는지 여부
역할 : 책임의 집합 (재사용성)
심판 → 경주 결과 (RacingResult)
진행자 + 서기 -> 경주 (Racing)
자동차 매니저 → 자동차 모음 (Cars)
자동차 → 자동차 (Car)

3. 설계 토대로 기능 구현 목록 만들기

용어 정의

경주(race) : 애플리케이션이 시작되어 경주가 시작되고 우승자가 나와 경주가 종료될 때까지를 의미한다.
이동(move) : 경주의 각 라운드를 의미한다. 매 이동(라운드)마다 자동차들은 전진하거나 안하거나 한다.
전진(forward) : 이동과 달리 실제로 자동차가 움직였는지 안움직였는지 여부를 표현한다.
결과값이 pobi : -- 라면 전진 횟수는 2회라는게 특정되는 반면, 이동 횟수는 알 수 없다.
위치(position) : 경주 결과로 출력되는 값으로 전진 횟수만큼 "-"를 그려 자동차의 위치를 시각적으로 표현한다.

Model

Car (자동차)

자동차 생성 기능
이름이 5자 초과면 예외 처리
전진 시도 기능
현재 상태 요약 기능

Cars (자동차들)

자동차들 생성 기능
중복된 이름 있으면 예외 처리
자동차들 이동 기능
자동차들 현재 상태 수합 기능

RacingResult (경주 결과)

우승 자동차 결정 기능

Racing (경주)

경주 생성 기능
이동 시도 횟수가 0 이하면 예외 처리
이동 기능
이동 가능 여부 결정 기능
현재 경주 상태 반환 기능
우승 자동차 반환 기능

RandomIntGenerator

0~9 사이의 랜덤 숫자 생성 기능

View

InputView

자동차 이름들 입력 기능 (String → List<String>으로 변환해 반환)
빈 리스트면 예외 처리
리스트 원소가빈 문자열이면 예외 처리
이동 시도 횟수 입력 기능 (String → int로 변환해 반환)
정수 아니면 예외 처리

OutputView

자동차들 위치 출력 기능
우승 자동차 출력 기능

Controller

RacingController

경주 세팅 기능 (자동차 이름, 이동 시도 횟수 입력 받아 자동차들, 경주매니저 생성)
경주 실행 기능 (각 이동마다 경주 상태 받아 출력)
경주 정리 기능 (우승자 받아 출력)

Exception

ErrorCode

예외 메시지 제공 기능

4. 마무리하며

이 글은 예제를 미션에 적용하는 과정 중심으로 썼기에
협력/책임/역할을 왜 나누는지에 대해서 궁금하신 분들은 책을 읽어보셔도 좋을 거 같습니다!
당장 미션 설계가 급하신 분들은 위 과정 그대로 따라해보셔도 좋고요ㅎㅎ
이 글을 공유하게 된 이유는 원래 위 과정을 리드미에 올려뒀는데
코드리뷰할 때 다른 분들로부터 생각보다 좋은 반응을 얻고서,
더 많은 분들께 공유해 도움을 드리고 싶어져서입니다!
전체 코드는 아래에서 볼 수 있습니다
894
pull
다들 프리코스 화이팅입니다!