2020년 12월 15일 화요일을 기준으로 우아한 테크코스 3기 프리코스가 종료되었다.
우아한 테크코스 지원 과정은 우아한테크코스 3기 지원 후기 포스트에 작성해두었다!
이번 포스트는 프리코스를 진행했던 과정과 배운 내용 등을 정리해보고자 한다.
⚾ 1주차 미션 - 숫자야구게임
숫자를 입력해주세요 : 123
1볼 1스트라이크
숫자를 입력해주세요 : 145
1볼
숫자를 입력해주세요 : 671
2볼
숫자를 입력해주세요 : 216
1스트라이크
숫자를 입력해주세요 : 713
3스트라이크
3개의 숫자를 모두 맞히셨습니다! 게임 종료
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1
숫자를 입력해주세요 : 123
1볼 1스트라이크
…
기능 요구사항 자체는 간단했지만, 프로그래밍 요구사항을 계속 의식해야 한다는 점과 이펙티브 자바를 읽으며 공부했던 내용을 적용해보자는 욕심 때문에 미션이 쉽게 느껴지지 않았다. 또한 정작 자바 언어 자체의 이해가 떨어지다 보니 이펙티브 자바 설계 패턴 적용은 커녕 전체적인 클래스 설계를 구상하는데에만 하루가 지나갔다.
설계 패턴을 포기하고 그 좋다는 TDD 라도 적용 해보고자 했지만 ‘이렇게 하는게 맞나? 먼저 구현하고 테스트하는게 나은거같은데?’ 라는 생각이 들어 도메인을 먼저 구현한 후 테스트를 진행했다. 결국 TDD 또한 지키지 못한 것이다. 설계 패턴과 TDD 모두 흐지부지 되자 이대로는 안되겠다 싶어 이펙티브 자바 책을 덮은 후 프로그래밍 요구사항에만 집중해서 미션을 진행했다. 다행히 구현 단계 동안은 미션에 푹 빠져들 수 있었다.
구현 단계에서 “함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.” 에 가장 신경을 곤두 세웠다. 메서드를 쪼개면 쪼갤수록 들여쓰기(indent)가 자연스레 적게 사용되고, 프로그램의 전체 흐름을 관리하는 클래스에서 메서드 이름만으로 메서드의 동작을 예측할 수 있다는 점이 너무 신기하고 재밌어서 계속 계속 쪼갰다. 그러자 아래 2가지가 눈에 보이기 시작했다.
- 메서드 네이밍
- MVC 관계
1. 메서드 네이밍
그동안 단순히 메서드 동작을 예측 할 수 있는 네이밍만 고려 했다. 그러자 아래와 같은 상황이 발생했다.
private void isWooWa(){ ... } // 그 놈이 그 놈인걸?
private boolean isTechCourse(){ ... }
구현과정에서 is 네이밍을 가진 메서드를 if 키워드 내부에 사용하려 했으나, 해당 메서드의 반환 타입이 void 형이라 에러가 발생하는 사건이 있었다. 내가 모든 메서드를 기억하고 있다면 문제가 없었겠지만, 메서드 동작을 잊어버린 경우 메서드를 이름에 의존해야 하는 상황이 존재한다는 걸 깨닫게 되었다.
“네이밍은 메서드 동작에 의한 결과 뿐만 아니라, 결과의 타입도 알게 하는게 좋다.” - 수 없이 많이 보아왔던 이론
이론으로 접했던 내용을 실제로 경험하고 나니 더욱 즐거웠다.
2. MVC관계
MVC관계는 마냥 즐겁지 못했다. 모델(도메인)을 어떻게 생각하고 구성 하느냐에 따라 모델-뷰-컨트롤러 각각이 짊어질 책임이 계속 달라졌다. 그러나 메서드를 쪼개면 쪼갤수록 모델-뷰-컨트롤러 간의 책임을 분배하기 용이해진다는 것 한 가지는 확실하게 느껴졌다.
특히 포비(박재성 님)의 목적의식 있는 연습을 통한 효과적인 학습 에 첨부되어 있는 프리코스 1,2,3주차 피드백을 훔쳐(🤷♂️?)보던 중 “객체를 직접 가져오지 말고 객체에 메세지를 보내라.” 라는 내용을 읽고 나서, 내가 구현한 컨트롤러가 모델 객체의 상태(멤버변수)에 직접 관여한다는 걸 깨닫고 해당 메서드를 도메인 객체 쪽으로 이동시켜 컨트롤러가 메세지를 보내기만 하도록 리팩토링을 진행했다. 그 덕분에 컨트롤러에게 몰려 있던 책임이 모델로 분배가 되는 효과를 볼 수 있었다.
👨🏫 1주차 미션 공동 피드백
- 의미 없는 주석을 달지 마라.
- 이름을 통해 의도를 드러내라. 축약하지 마라.
- 메서드 이름에 의존하는 것을 이미 경험했다.
- 네이밍은 상세 할수록 좋다.
- 개발도구의 code format 기능을 활용해라.
- IntelliJ 기준 Cmd + Opt + Shift + L
- 스타일.xml 파일 적용하면 알아서 다 해준다. 아주 달콤하다.
- 공백(space) 하나도 convention 이다.
- 불필요하게 공백라인(enterline)을 만들지 않는다.
- space와 tab을 혼용하지 마라.
- 구현 순서도 convention이다.
class A { 1. 상수(static final) 또는 클래스 변수 2. 인스턴스 변수 3. 생성자 4. 메소드 }
- 반복하지 마라.
- 만악의 근원이다.
- 반복할 일이 생기면 메서드화 시키자.
- 하드코딩 하지 마라.
- 상수처리 할 것.
- 가능하면 Enum도 좋다.
- git commit 메세지를 의미있게 작성해라.
- README.md 를 상세히, 꾸준히 업데이트 하라.
1주차 미션을 마무리 한 후, ‘벽을 만져는 봤다’ 라는 느낌이 들었다.
“함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.” - 프리코스 3주간의 공통 요구사항
메서드를 최대한 쪼갠 것이 그런 느낌을 준 주역인 것 같았다.
미션을 진행하면서 혼났던 설계 패턴과 TDD 모두 “이래서 필요하다.” 라는 목적 없이 “좋다니까 일단 해보자.” 라는 생각으로 접근한 것이
문제였음을 느낀 후 이펙티브 자바 책을 덮어두고, 자바 기본서를 읽어 나갔다.
🚗 2주차 미션 - 자동차 경주 게임
경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)
pobi,woni,jun
시도할 회수는 몇회인가요?
5
실행 결과
pobi : -
woni :
jun : -
pobi : --
woni : -
jun : --
pobi : ---
woni : --
jun : ---
pobi : ----
woni : ---
jun : ----
pobi : -----
woni : ----
jun : -----
최종 우승자: pobi, jun
2주차 미션을 진행하면서는 아래 4가지를 중점적으로 고민했다.
- 입력 값 검증(예외처리) 위치
- 확장성 고려하기
- 객체간 불필요한 정보공유 제한
- 객체가 아는 것을 최대한 줄이기
1. 입력 값 검증(예외처리) 위치
1주차 미션과 더불어 2주차 미션에서도 사용자 입력값의 검증을 뷰(View)단계에서 진행시켰었다.
‘완벽한 값을 입력 받고 난 후에 로직을 수행시키자’
라는 강박 때문이었다. 그러나 검증이 완료된 문자열을 🚗Car로 전달하는 컨트롤러 구현과정에서 실수로 🚗Car에게 빈 문자열을 전달했고, 아무 이름이 없는 🚗Car들이 생성되는 결과를 경험했다. 즉! 이전의 검증이 아무런 효력이 없어진 것이다. 테스트 단계에서 직접 문자열을 삽입했음에도 알아차리지 못한 문제를 구현 단계에 와서야 알게 되었다. 프리코스 진행 내내 영영 모를 수도 있었는데 참 운이 좋았다고 생각한다.
어쨌거나 이 사건 덕분에 뷰에서 진행했던 검증을 각 모델 객체의 생성자 쪽으로 이동시켰다. 이 덕분에 뷰마다 중복되었던 검증이 줄어듦은 물론, 자연스럽게 객체값 검증 관련 상수들이 객체 내부로 들어와 객체의 값이 어떤 기준을 갖고 생성되는지 가독성이 올라감을 느낄 수 있었다.
2. 확장성 고려하기
1주차 미션에서 static 개념을 제대로 이해하지 못한 상태로 구현을 진행했었다.
‘어차피 유저가 사용할 객체 하나, 컴퓨터가 사용할 객체 하나라면 static으로 막아버리는게 낫지 않을까?’
‘오, static 을 이용하니 컨트롤러에서 new로 생성할 필요 없이 깔끔해보이게 짤 수 있구나~’
혼자 생각하기엔 그럴듯 했지만, 기본서를 읽으며 배운 내용을 토대로 다시 1주차 코드를 다시 살펴보니 수 많은 규칙을 위배하고 있었다. 😅
“객체에 상태(변수)가 없을 경우 객체의 동작(메서드)은 static”
“객체의 인스턴스 변수와 클래스 변수는 공개하지 않는게 좋다. (메서드로 감싸라)”
“멤버에서 클래스 변수를 조작하게 하지 말고 별도의 클래스 메서드를 제공해라”
- Agile Java
다른 사람이 보기에 확장성은 전혀 고려하지 않고, 클래스 변수를 모조리 공개한 위험한 코드 였다. 같은 잘못을 반복하지 않기 위해 이번 미션을 진행하면서는 위 3가지 규칙을 계속해서 읊으면서 단순한 상태나 동작 하나라도 클래스로 쪼개려고 노력했다.
🚗Car객체의 경우, 랜덤한 값 범위에 따른 전진이 언제든지 다른 전진 로직으로 변경될 수 있다고 생각하여 ⛽GasTank라는 새로운 객체를 만들어 이동 진행과 이동 결정을 나누었고, 🏁Lap 또한 레이싱의 종료 기준이 언제든지 바뀔 수 있기 때문에 🏁Lap을 객체로 만들어 레이싱 진행/종료를 결정시켰다.
3. 객체간 불필요한 정보공유 제한
2주차 미션 초기 설계에선 컨트롤러에 해당하는 클래스에서 🚗Car 생성자와 ⛽GasTank 생성자를 모두 호출해서 🚗Car객체를 만들어냈다. 그러나 메서드를 최대한 쪼개는 리팩토링 과정에서 “컨트롤러가 🚗Car 내부의 ⛽GasTank를 알 필요가 있나?” 라는 의문이 생겼다.
🚗Car 생성자 내부에서 ⛽GasTank 생성자를 호출하도록 하니, 컨트롤러는 ⛽GasTank의 존재를 모름에도 정상적으로 수행됐다.
이러한 현상이 추후 도메인 확장이나 교체 과정에서도 유지보수성을 높여줄 것이라는게 느껴졌다!
4. 객체가 아는 것을 최대한 줄이기
컨트롤러를 리팩토링하는 과정에서 “우승자를 기록하는 멤버변수를 지워버릴까?” 라는 고민이 생겼다.
당장 소수의 메서드 작성에 편리함을 제공해주었지만, 우승자 멤버변수의 속성이 변화할 때마다
우승자 목록을 사용하는 모든 메서드를 수정해야하는 복잡함이 뒤따랐다.
또한 상위 클래스가 아는 것(멤버변수)이 많아질수록 하위 객체에 메세지를 보내기보다
하위 객체의 값을 끌어와 자신에게 저장하는 식으로 ‘객체에 메세지를 보내라’가 지키기 어려워졌다.
이 때문에 필수라고 생각되지 않는 (다른 멤버변수를 통해 추출할 수 있는) 멤버변수를 과감하게 쳐냈다.
멤버변수를 쳐내다보니 필수로 보이는 멤버변수가 딱 1개 남아
일급 컬렉션 개념도 적용이 가능할 것 같아서 시도해보았지만,
제대로 적용한 것인지는 사실 아직까지도 확신이 생기지 않는다…
(일급 컬렉션 개념은 더 복잡한 구조에서 경험해봐야할 것 같다.)
👨🏫 2주차 미션 공동 피드백
- README.md 기능구현 목록을 너무 상세히 적지 않는다.
- 기능의 구현 방식은 구현 단계에서 얼마든지 바뀔 수 있다.
- 구현할 기능목록 자체를 정리하는 것에 집중하자.
- Java api를 적극적으로 활용하자.
- stream, asList 등을 몰라서 for반복문으로 루프를 돌린 경우가 많았다.
- 3주차 미션에서는 stream을 활용하자!!
- 객체에 메세지를 보내라
- 객체의 상태를 끌어오는 것은 안좋다.
- “현관문 비밀번호를 바꿔라.” 를 기억하자.
- 필드(인스턴스 변수)를 줄여라
- 객체의 복잡도가 커진다.
- 필드가 줄어들면 일급 컬렉션도 가능해진다!
- 비즈니스 로직과 UI를 분리시켜라.
- 하나의 클래스가 두 가지 모두를 책임지게 하지 말자
- 단일 책임의 원칙에도 위배된다.
- 예외 케이스를 항상 고민해라.
2주차 자동차 경주 게임 미션을 진행하면서 가장 문제가 되었던 것은 조급함과 욕심이었다.
‘정적 팩터리 메서드를 적용해볼거야.’
‘일급 컬렉션을 적용해볼거야.’
‘사용자 입력값 검증을 뷰(View)에서 도메인(Domain)으로 옮기자.’
하나씩 충족 시켜도 낯선 개념들을 모두 충족 시키는 코드를 작성하는 건 쉽지 않았다.
(이 때문에 커밋 내역을 되돌리고 로컬 프로젝트를 모두 삭제하고 다시 클론 하는 등 깃 사용법은 많이 익히게 되었지만… 😂)
결국 돌고 돌아, 하나씩 이해하고 경험을 쌓은 뒤에 다음 개념을 접하자 라고 마음을 먹은 후에야 리팩토링이 진행할 수 있었다.
또한 1주차보다 조금 더 적극적으로 TDD를 시도하면서 아래와 같은 생각이 들었다.
‘처음부터 완벽한 메서드를 구상하고 테스트를 작성하는 것이 아니라, 원시적인 메서드를 작성해 테스트를 진행한 후 리팩토링 해나가는 것.’
🚇 3주차 미션 - 지하철 노선도
## 메인 화면
1. 역 관리
2. 노선 관리
3. 구간 관리
4. 지하철 노선도 출력
Q. 종료
## 원하는 기능을 선택하세요.
4
## 지하철 노선도
[INFO] 2호선
[INFO] ---
[INFO] 교대역
[INFO] 강남역
[INFO] 역삼역
[INFO] 3호선
[INFO] ---
[INFO] 교대역
[INFO] 남부터미널역
[INFO] 양재역
[INFO] 매봉역
[INFO] 신분당선
[INFO] ---
[INFO] 강남역
[INFO] 양재역
[INFO] 양재시민의숲역
마지막 미션으로는 linked-list가 떠오르는 지하철 노선도 미션이 진행되었다. 마지막 미션 동안 가장 고민했던 부분은 아래 5가지다.
- 클래스간 책임 분배와 교류
- 검증(예외처리) 위치에 대한 고민
- ‘객체에 메세지를 보내라’에 갖힌 것
- Enum 활용
- 구현 순서(도메인부터? 컨트롤러부터?)
1. 클래스간 책임 분배와 교류
1~2주차까지 해온대로 무작정 도메인(모델)부터 구현을 시작했지만, 도메인 간의 관계가 생각보다 더 복잡하다는게 점점 느껴졌고 일급 컬렉션으로 활용될 수 있는 Repository클래스(🚉StationRepository, 🛣️LineRepository 등)의 책임이 점차 과하고 무거워지는게 느껴졌다. 즉시 구현을 멈추고 전체적인 설계부터 다시 그려나갔다.
설계를 그려나가면서 🚉Station, 🛣️Line, ➰Section 간의 데이터 교류를 위한 클래스가 따로 존재하면 좋겠다는 생각이 들었다. Repository 클래스는 객체를 리스트로 묶어놓아 이미 많은 CRUD 메서드를 갖고 있음에도 추가적으로 다른 객체(도메인)들과 교류하는 메서드와 뷰(View)에 송출하는 메서드를 가져야한다는게 부담으로 느껴졌다.
이 때문에 Service라는 추가적인 클래스를 만들어 자신이 아닌 다른 클래스들과 통신은 모두 Service 클래스를 통하도록 구현했다. Repository 클래스는 CRUD만 직접적으로 관리하고, 그 외 모든 메서드는 Service에서 진행되었다. 설계도와 같이 서로 다른 객체간의 통신을 모두 Service 한 곳에서 제한하는 효과를 가질 수 있었다. (다 구현하고 나서 보니, 다들 Service 클래스를 만들었더라… 😆)
2. 검증(예외처리) 위치에 대한 고민
2주차 미션에서의 경험으로 인해 검증은 가장 작은 도메인 쪽에서 진행하는게 무조건 좋다고 생각했다 (보통 가장 작은 도메인 객체에서 데이터의 변화가 일어나기 때문에). 그러나 이번 3주차 미션을 진행하면서 작은 도메인 검증이 무조건 좋은 것은 아니라는걸 느끼게 됐다.
## 노선 관리 화면
1. 노선 등록
2. 노선 삭제
3. 노선 조회
B. 돌아가기
## 원하는 기능을 선택하세요.
1
## 등록할 노선 이름을 입력하세요.
1호선
## 등록할 노선의 상행 종점역 이름을 입력하세요.
강남역
## 등록할 노선의 하행 종점역 이름을 입력하세요.
잠실역
[INFO] 지하철 노선이 등록되었습니다.
위 예시에서 사용자는 총 4번의 입력을 진행한다. 나는 사용자의 편의를 최대화 하고자 매 입력 순간마다 예외처리(등록할 노선 이름이 존재하지 않는다던지)가 진행되길 원했다. 그러나 검증 메서드를 작은 도메인에 위치시킬 경우엔 4번의 입력이 모두 끝난 후에야 검증이 가능했다. 이 때문에 Service 클래스 쪽으로 검증 메서드를 끌어올리게 되었다.
‘나중에 다른 서비스 로직이 추가되면 매번 검증 메서드를 호출해야하는데? 작은 도메인 객체에서 검증을 진행하는게 맞지 않아?’
‘메서드를 더욱 잘게잘게 쪼갰다면 작은 도메인 쪽에서 매 입력 순간마다 검증이 가능하지 않았을까?’
라는 의구심이 남아있지만, 현재까지는 적합하다고 여겨진다면 도메인-서비스(컨트롤러)-뷰 단계 가리지 않고 역할에 알맞는 위치가 정해지면 그곳에서 시작하는게 좋다고 생각하고 있다.
3. ‘객체에 메세지를 보내라’에 갇힌 것
한동안 ‘객체에 메세지를 보내라’에 갇혀서 getter 메서드가 만들어지는 상황을 최대한 피했다. 그러나 도메인의 현재 상태를 출력 시키기 위해선 getter 메서드를 사용해야했다. 그렇지 않을 경우 객체에 메세지를 보내는 것보다 중요한 단일 역할의 원칙이 무너졌다.
즉, 도메인의 상태(멤버 변수)를 건드리는 로직에선 getter 메서드를 최대한 피하는 것은 맞으나, 출력 등 getter 메서드가 필요할 때는 확실히 쓰는게 맞다는 걸 깨닫게 되었다.
4. Enum 활용
if-else 키워드에 대한 제한이 존재했기 때문에(switch 키워드도 안된다!) 화면 분기를 어떻게 해야하나 고민이 많았다.
‘화면 하나 하나를 모두 객체로 만들어서 List에 삽입할까?’
‘화면별 메뉴에 대해서는 어떻게 하지?’
‘깔끔한 방법을 사용하고 싶은데…’
도저히 감이 잡히지 않아 다른 참여자분들의 설계를 참고했다. 그 과정에서 Enum을 활용한 것이 눈에 띄었다. 당장 내가 Enum 활용을 통해 느낄 수 있는 장점은 3가지 였다.
- 가독성이 좋다. 구현 의도가 열거임이 명확하다.
- 예외처리가 간결해진다. Enum에 속하지 않으면 전부 자동 예외다.
- 인스턴스 생성과 상속을 방지한다.
단점으로는 Enum 을 공부해야한다는 점이었다. 단점보다 장점이 더 많았으므로(🥊) 결국 Enum 을 통해 구현을 진행했다.
결국 위와 같은 구성을 갖게 되었다. Display 클래스는 모든 Display 클래스들이 동일하게 사용하는 메서드들을 모아서 상속 받아 사용하도록 했고, 각각의 Display 클래스에서 사용자 입력을 받고, Menu 클래스에서 해석 후 Service 클래스로 전달하는 로직을 갖게 되었다.
5. 구현 순서(도메인부터? 컨트롤러부터?)
1~2주차 까지는 작은 도메인에서부터 구현을 진행했다. 그러나 3주차 미션에서는 도메인들의 구현이 진행 될수록 도메인간의 (현재시점에서)불필요한 관계가 계속해서 떠올랐다.
결국 도메인 구현을 잠시 멈추고 전체 서비스 로직(컨트롤)부터 구현을 진행했다. 개인적으로는 작은 도메인부터 구현을 시작해나가는 것보다, 전체 서비스 로직을 마련한 후 도메인을 파고드는 것이 현재 계획하는 서비스에 가장 알맞는 형태로 도메인을 추상화 하기 쉬웠고, 로직별로 예외처리가 또한 중복 되는 일도 막을 수 있었다.
이 때문에 마지막 최종 테스트도 전체 서비스 로직부터 구현을 진행해야겠다고 마음먹게 되었다.
3주차 미션을 진행하는 동안은 그 무엇보다 ‘공통 피드백’을 지키려고 더욱 안간힘을 썼다. 특히 하드코딩 하지 마라, 축약하지 마라 등 연속으로 강조되는 피드백은 거의 무조건 지켰던 것 같다.
3주차 미션은 압도적인 난이도에 시간이 촉박할 것 같아 ‘이걸 적용해봐야지!’ 라는 생각보다는, ‘이걸 적용해도 되는 건가?…’ 라는 생각으로 불안불안하게 미션을 진행했던 것 같다. 특히 이전 미션들과 달리 Model-View-Controller 중에서 비교적 낮게 느껴졌던 View 비중이 갑자기 뛰어올라서 적지 않게 당황했다. Model-View-Controller 모두 확실하게 분배되고 다시 결합되어야 한다는 걸 새삼 느꼈다.
🔥 불타올랐던 3주를 보내고
개인적으로 무아지경(無我之境)을 굉장히 좋아한다. 시야가 모니터 영역으로 좁아지고 이어폰에서 흘러나오는 노래가 들리지 않으며 눈동자와 손가락만 움직이는 상태에 빠지곤 한다. 극도로 집중력이 올라간 무아지경 상태에선 3시간 걸릴 일을 1시간에 끝내는 기적을 만들어낸다.
프리코스 초반엔 무아지경에 빠져들지 못했다. 신나게 기능을 구현하다가도 ‘이게 맞나?’ 라는 질문을 끊임없이 되새겨야 했고, 모두가 이해하기 쉬운 코드를 작성해야 한다는 중압감에 무아지경의 문턱을 오고갔다.
그러나 프리코스 후반에 들어서자 조금씩 무아지경에 빠져들 수 있었다. 중압감에 무뎌지고 자연스럽게 컨벤션이 몸에 베어드는, 단순한 코드 1줄도 “여기서 이걸 읽으면 이렇게 해석되겠지?”를 혼자 중얼 거리는 사람이 되어가고 있었다.
혼자 대단한 기능을 구현하는 사람이 아니라, 함께 일하기 좋은 사람을 만드는 과정
프리코스를 시작하기 전부터 코딩 컨벤션에 관심을 갖고 있었다. 그러나 관심만 갖고 있었을 뿐, 정작 무엇부터 공부해야할지 몰랐고 의욕적으로 컨벤션을 공부하고 적용할 매개체도 없었다. 자기소개서에 “개발자는 평생 공부하는 직군이라던데, 혼자 공부하는 방법을 모르겠습니다. 우아한테크코스에서 공부하는 방법을 배우고 싶어요.” 라는 이야기를 적었었다. 프리코스는 공부하는 방법을 알려주고 목적의식을 갖기 위한 매개체를 제공해주는 감사한 시간이었다.
💻 최종 테스트
어느 덧 최종 테스트만 앞두고 있다. 가장 걱정되는 것은 역시 시간 제한이다. 끊임없이 고민해야하는 컨벤션을 지키면서 올바른 기능까지 구현해야한다는 압박감…
나는 1~3주차 미션을 진행하면서 평균 이틀 이상이 소요되었다. 대부분의 시간이 예외처리와 뷰(View) 구성에 소요되었던 걸 생각해보았을 때, 이를 정리해놓는 것으로 도메인 및 전체 서비스 로직 구성 시간을 확보할 수 있지 않을까 생각중이다.
“프리코스만 맛봐도 참 감사하겠다.” 라는 말을 적었었는데, 막상 프리코스를 맛보고 나니 테크코스가 더욱 절실해졌다. 열의에 가득찬 예비 개발자분들과 한 곳에서 소통할 수 있다는 것은 놓치면 평생 후회할 엄청난 메리트가 분명하다. 참 ‘간사’한 사람인 것 같다. 😅
할 수 있는 최선을 다해서 최종 테스트를 준비해보자!
댓글남기기