본문 바로가기
2023-woowacourse-precourse

2023 우아한 테크코스 1주차 회고

by JHyun0302 2023. 10. 27.
728x90

지난 시간을 돌아보며...

 

 

2023년 10월 19일 ~ 2023년 10월 25일, 7일간 우아한 테크코스 줄여서 우테코 1주차 과제가 진행되었다.

사실... 작년에도 우테코에 참여했었지만 자바 기본 문법, git 사용법 등 백지 상태로 박치기(?) 했었다... 결과는 안봐도 뻔했다...

그리고 1년간 java, Spring Framework, JPA, DB, CS 등을 공부하며 백엔드 개발자로서 꿈을 키워나갔다.

 

2022년 INFCON에서 영한님의 말씀처럼 "시스템"처럼 행동했다.

 

작년 1주차 문제는 알고리즘 7문제가 과제로 주어 줬었지만 2023년 우테코 1주차 문제는 "야구 게임 문제" 였다!!

(어딘가 낯 익은 문제였다... 사실 작년에 뵌 적 있는 과제였던 걸지도...?)

 

작년에는 OOP, 객체지향, 클래스 개념, 자바 기본 문법 등 클린 코드 단어 조차 몰랐던 상태였었다...

하지만 야구 게임 요구사항을 보자마자 머릿속에서 domain을 어떻게 정의할까? 어떤 클래스에 어떤 메서드를 넣어야 할까?

어떤 클래스끼리 의존 관계를 맺으면 좋을까?  등 고민 X 100000... 이 되었지만 흥미로웠다!!

(몰입의 첫 단추를 끼운걸지도...?)

 

그리고 작년 우테코와 다른 점은 디스코드를 통해 사람들과 커뮤니케이션이 가능했다는 점!!

'나'의 고민을 똑같이 하는 사람들도 있었고 서로 코드 리뷰도 하고 일상도 공유하고 좋은 말씀들도 들을 수 있는 공간이 생겨 amazing 했다

 

 


1주차 미션 소개 & 나의 로직 설명

 

 

1주차 미션 : https://github.com/JHyun0302/java-baseball-6

 

GitHub - JHyun0302/java-baseball-6: 우아한 테크코스 프리코스 1주차 과제 (2023.10.19~2023.10.25)

우아한 테크코스 프리코스 1주차 과제 (2023.10.19~2023.10.25). Contribute to JHyun0302/java-baseball-6 development by creating an account on GitHub.

github.com

 

 

+ 클린코드를 지향하기 위한 체크리스트 : https://github.com/woowacourse/woowacourse-docs/blob/main/cleancode/pr_checklist.md

 

 

 

 

1주차 미션은 다행히 크게 어렵지 않았다!! (1년 전에는 왜 스파게티를 만들었니,,)

 

 

Safe!!

 

 

 

나는 클래스를 만들때 항상 SOLID 원칙 중 SRP를 고민한다. (한 클래스가 하나의 책임만 지고 있나?)

그리고 '어떤 메서드가 어떤 클래스에 들어가면 좋을까?' 에 대한 대답은 다음과 같다.

 

1. 객체의 행동과 연관된 메서드는 객체와 함께!

2. 클래스와 공통 속성을 가진 메서드끼리 묶기!

 

 

 

야구 게임에서 내가 정의한 객체는 2가지 : computer & user

 

1. computer : 'camp.nextstep.edu.missionutils.Randoms'을 이용한 랜덤 값

- 랜덤 값을 저장할 변수

2. user : 사용자가 입력한 값

- 사용자가 입력한 값을 저장 할 변수
- 점수 저장하는 변수 (strike, ball)

 

 

다음은 내가 정의한 "Service Class & 그 클래스에 정의한 main method"이다.

 

```
1. MakeComputerRandom : createRandom()
2. MakeUserAnswer : input()
3. UserValidation : validation(), restartValid()
4. Play : playBaseballGame()
5. PrintResult : result()
6. Restart : restartOrExit()
```

 

 

 

참고 : 메서드 로직 설명

- createRandom() : 'Randoms()'을 이용해 컴퓨터의 랜덤 값 생성
- input() : 사용자 입력 받기 + 검증 로직 실행
- validation() :
  1.입력된 값이 서로 다른 값인지 검증
  2.숫자가 입력됐는지 검증
  3.100~999 사이 숫자인지 검증
- playBaseballGame() :
    1. 유저가 입력한 값이 컴퓨터의 값에 포함되어 있다. && 두 인덱스까지 똑같다. -- strike
    2. 유저가 입력한 값이 컴퓨터의 값에 포함되어 있다. && 두 인덱스는 다르다. -- ball
    3. strike와 ball값을 User 객체에 저장
        - 이유 : User가 입력한 값에 의한 결과 값이므로 User 객체에 묶는게 좋다고 판단
- result() : User에 저장된 strike & ball 변수를 이용해 결과 출력
- restartOrExit() : '3 스트라이크' 인 경우 재시작 or 종료를 위해 사용자 입력 받기 + 검증 로직 실행
- restartValid() :
    1. 입력된 값이 숫자인지 검증
    2. 입력된 값이 1 or 2인지 검증

 

 

 

 


성장 포인트

 

프로그래머는 꾸준히 공부해도 성장할 여지가 있어 오.히.려 좋.아!!

 

1. else 예약어 삭제 : 리팩토링하기 전 구현에만 집중할 때는 if-else 문을 통해 구현했었을 때는 복잡성이 아주 많이 증가했었다.
리팩토링을 통해 메서드를 분리하고 분기 문을 추가한 덕분에 else 에약어를 삭제할 수 있었고 복잡성도 현저히 낮췄다!!

 

2. static 예약어 : 'static? 정적 변수 선언 할 때 쓰는거 아냐?' 라고 생각하고 무심코 넘어갔었다. 그래서 처음 생성자 주입을 시도했을 때 'private static final ${클래스명} ${변수명}' 과와 같이 되었고 모든 메서드에 static을 붙어야만 했다...
고민하던 찰나 디스코드에서 '나'와 비슷한 고민이 올라왔다. GoSu 분의 대답을 보고 고민 해결!!

 

 

GoSu 분의 답변

설계자의 생각에 따라 다르겠지만, 개인적으로는 어떤 객체의 주체적인 행동과 관련된 메서드라면 static을 붙이는 것이 어색하고, 그렇지 않은 메서드라면 static을 붙이는 것이 좋아보여요.

위에서 이야기하신 객체를 생성하는 정적 팩토리 메서드의 경우에는 객체의 주체적인 행동이라기보다는 객체 이외의 존재가 객체를 생성하는 것이기 때문에 static을 사용하는 것이 자연스럽게 보입니다.

반면에 메서드가 어떤 객체의 주체적인 행동인데, 그것이 static이 붙어서 전역적으로 사용된다면 어색하게 보일 수 있을 것 같아요.

저도 공부하면서 개인적으로는 이런 생각을 가지고 사용하고 있는데, 여러 가지 생각을 들어보면서 같이 고민해보면 좋을 것 같습니다.

예를 들면, 어떤 클래스가 update() 라는 메서드를 가지고 있고, 이 메서드가 자기 자신의 개인적인 상태나 정보를 바꾸는 행위라면, 이것은 그 객체의 주체적인 행동이어야 해요. 
그렇지 않으면, 객체 이외의 존재가 개인적인 정보를 바꿀 수 있는데, 그 객체가 정보를 공유하도록 설계되지 않은 이상 굳이 그 객체 이외의 존재가 자기 자신을 바꾸게 두는 것은 어색하다고 보는 거예요. 
update() 같은 직접적인 상태 변화를 유도하는 메서드가 아니더라도, '어떤 객체가 주어진 매개 변수를 가지고 무언가를 한다' 라고 생각하면 조금 더 와닿을 수 있는 표현일 것 같습니다.

 

 

3.  3개 이상 인스턴스 변수 가지는 클래스 없애기 : 단순한 조건이지만 막상 이 규칙을 지키며 구현해 보니 답답하다... 가능한 인스턴스 변수를 줄이며 리팩토링했지만, 아직 부족한 부분이 많다는 것을 느꼈다,,

 

4. Test Case 작성 : 구현이 끝나고 테스트 케이스 작성해 검증하였다. 그 과정에서 예상치 못한 예외 상황들도 발견할 수 있었고 클래스 간 의존성도 제거할 수 있었습니다. 예를 들어 PrintResult(결과를 출력하는 클래스)에서 바로 Restart(재시작을 유도하는 클래스)를 호출하지 않고 Boolean 값을 반환해 주고 메인 메서드에서 반환 값에 따라 Restart 클래스를 호출할지 말지 결정하는 방식으로 수정하였다.

 

 

 

 

 


간단한 프로그램 만드는데도 클린 코드를 지향하며 코드를 짜는건 쉽지 않다.. (스파게티 그만!!)

 

몰입해서 7일이 금방 지나갔고... 2주차 과제도 화이팅!!

 

 

 

 

 

 

 

 

 

 

INFCON2022 : [https://www.youtube.com/watch?v=QHlyr8soUDM]

 

 

반응형