Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[자동차 경주] 정찬호 미션 제출합니다. #116

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

chanho0908
Copy link

개인 실수로 PR을 Close 시켜버려서 다시 생성합니다.
원칙상 미제출로 처리된 다는 것은 알지만 그래도 올려놓겠습니다 !
비록 이 실수로 인해 우아한 테크 코스와 함께하지 못하게 된다 하여도
4주간 프리코스의 목표인 개인의 성장을 위해 계속해서 열심히 문제 수행하겠습니다!
원본 출처 : #13

- 첫번째 미션에서 놓치고 있던 문제들을 되새기기 위해 리마인드 파트를 작성하였습니다.
- 프리코스를 통한 성장을 위해 이번 도전에서 달성 하고자 하는 목표를 설정하였습니다.
- 문제를 기능별로 분류하여 요구 사항 분석을 작성하고 해당 순서대로 커밋합니다.
- 기능별 예측 가능한 에러들을 테이블로 분석하여 작성하였습니다.
- 기능 요구사항, 에러 사항들을 놓치지 않기 위해 체크 리스트를 작성하였습니다.
- 기능 요구사항 수정
  - 이동 횟수 상한값 조건 추가
  - 게임 진행 중 진행 상황 출력 조건 추가
  - 실행 결과 예시 추가

- 프로그래밍 요구 사항 추가

- 자동차 이름 입력 에러 명서세 수정
  - 이름이 중복되는 경우 예외 메시지 수정(이름은 ,로만 구분해주세요 -> 동일한 이름은 사용하실 수 없어요)
  - 쉼표가 아닌 구분자가 들어올 경우 예외 메시지 수정(이름은 ,로만 구분해주세요 -> 구분자는 쉼표(,)로 입력해주세요)
  - 플레이어가 2명 미만인 경우 에러처리 추가 : 혼자선 게임을 플레이 하실 수 없어요 플레이어는 2명 이상 입력해주세요

- 이동 횟수 입력 에러 명세서 수정
  - 문자와 숫자가 섞여 있는 경우 : 이동 횟수는 정수로만 입력해주세요

- 이동 횟수 상항값 수정 : 1,000 -> 10,000
- MIN_RANDOM_NUMBER : 랜덤 이동값 최소 범위
- MAX_RANDOM_NUMBER : 랜덤 이동값 최대 범위
- MIN_MOVE_COUNT = 전진 조건 최소값
- SEPARATOR : 구분자
- MAX_PLAY_COUNT : 최대 게임 플레이 횟수
- REGEX_FOR_INVALID_SEPARATORS : 영어/한글/숫자/모음/자음/구분자만 받는 정규식
- MESSAGE_GUIDE_FOR_USER_NAME : 게임 시작 안내 메시지
- MESSAGE_GUIDE_FOR_INPUT_COUNT : 게임 횟수 안내 메시지
- MESSAGE_RESULT : 실행 결과 안내 메시지
- MESSAGE_LAST_WINNER : 최종 우승자 안내 메시지
사용자에 의도(intent)애 일어날 수 있는 상황을 sealed class로 정의했습니다.
- NameErrorDelegator.kt : Delegate Pattern을 사용해 이름에 대한 에러처리 로직을 위임
- PlayerCountErrorDelegator.kt : Delegate Pattern을 사용해 시도 횟수에 대한 에러처리 로직을 위임
- ValidationDelegator.kt : 이름, 시도 횟수에 대한 에러 처리 로직을 모두 합쳐 수행
- DependencyInjector.kt : 미션에 사용될 모든 Class의 의존성을 관리하는 Dependency Container Class
- CarRacingState.kt : 미션중인 자동차 상태, 게임 결과 상태 관리 Class
    + PlayerState : 자동차마다 시도별 자신의 결과를하는 출력하는 책임을 가지도록 설계
    + PlayResultState : 게임 결과를 출력하는 책임을 가지도록 설계

- RacingViewModel.kt : 모든 비즈니스 로직을 처리하는 Class
- Application.kt : 앱의 시작점으로 Dependency Container주를 View에 주입
 랜덤값에 따라 이동이 가능하다면 기존 상태에 랜덤값을 추가해 새로운 상태를 반환합니다.
이동 횟수 생성 로직을 SAM 인터페이스로 분리하여 책임을 명확히 했습니다.
Kotlin의 SAM 변환을 활용해 코드의 간결성과 유지보수성을 향상시켰습니다.
moveCountFactory 생성의 책임은 DependencyInjector가 가지도록 해 제거했습니다.
UserInputIntent 를 RacingViewEvent로 변경합니다. MVI와 MVVM를 비교한 그림을 보면 Intent는 MVVM의 ViewModel Layer에 해당합니다.
때문에 View에서 Intent를 사용하는 것은 경계를 침범한다고 생각했습니다. 그래서 사용자의 "의도"를 직접적으로 코드에서 표현하는 것 보다 사용자의 "이벤트"를 표현하는 것이 View 영역에서 가져야할 책임(사용자와의 상호작용)이라고 생각해 수정했습니다.
ViewModel에서 별도로 관리하던 플레이어와 게임 횟수를 하나의 상태 관리 클래스를 사용해 캡슐화해 사용하도록 수정했습니다.
@jhseo12
Copy link

jhseo12 commented Oct 29, 2024

다시 PR 재오픈 가능합니다.

@chanho0908
Copy link
Author

다시 PR 재오픈 가능합니다.

저두 PR이 살아있으면 다시 열고싶지만
커밋 취소할게 있어서 구글링한 방법대로 했다가 force push를 하니 기존 PR이 아에 close되버렸네요 하하...

Copy link

@liqurt liqurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드의 로직이나 테스트 코드를 보면 꼼꼼하고, 무엇을 의도했는지가 드러나요.
DI 관련된 코드에서는 저의 몰이해 때문인지 여기서 굳이 왜 필요한지 의문이 생겼습니다.


---

## 🏴‍☠️ 이번 미션에서 도전할 목표
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 문장이 좋아요, 무엇을 왜 했는지 라는 것

@@ -0,0 +1,16 @@
package racingcar.delegate.name
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readme에 일단 무엇이 예외인가? 를 적고 인터페이스에 정리하고 인터페이스 구현체를 쓰는 이 흐름이 좋아요

package racingcar.constans

object NamingError {
val errorMessageForEmptyInput by lazy {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

질문
이곳의 변수들도 기존의 상수인 Constatnts.kt 처럼 선언할수 있었는데 굳이 뒤에 by lazy 키워드로 붙여서 선언한 이유를 알고 싶어요

Copy link
Author

@chanho0908 chanho0908 Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

object 키워드의 경우 싱글톤을 만드는 키워드로
싱글톤 클래스의 경우 메모리에 항상 존재하게 됩니다 !

이 경우 사용하지 않는 내부 요소들까지 메모리에 올라가게 되어 메모리 릭을 발생시키게 되는데 여기 있는
변수들은 에러 상태일 때만 사용되기 때문에 해당 상황에서만 사용하도록 하기 위해 요렇게 했습니다 !

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constants.kt 에 있는 상수는 사용여부도 상수고 NamingError.kt의 상수는 쓸지 말지의 여부는 미지수라서 쓸때만 메모리를 사용한거군요!

상수라도 사용여부조차 찐상수가 있고, 애매한 상수가 있다는 점을 배워갑니다!

Copy link

@cheonjiyun cheonjiyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소한 예외까지 꼼꼼하게 신경쓰신게 보여서, 저에게 부족했던 열정을 느끼고 갑니다..!! ㅜ

Comment on lines +2 to +13

fun String.isNotNumeric(): Boolean {
return this.toDoubleOrNull() == null
}

fun String.isFloat(): Boolean {
return this.contains(".")
}

fun String.isNegativeNumber(): Boolean {
return this.toIntOrNull()?.let { it < 0 } ?: false
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검사하는 함수를 따로 만들어 놓으니 간편해 보이네요. 한번 감싼 함수의 이름이 알아보기 쉬워서 좋았습니다!

Comment on lines +74 to +81
fun `시도 횟수가 0일 때 예외 테스트`(){
val input = 0
val exception = assertThrows<IllegalArgumentException>{
playCountErrorDelegator.checkInvalidPlayCountByZero(input)
}
assert(exception.message == errorMessageForInValidPlayCountByZero)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 시도횟수가 0일 때는 생각못했는데, 유효성검사가 꼼꼼하시네요..!

Comment on lines +21 to +24
- 내가 생각하는 좋은 코드는 무엇이며 좋은 아키텍처는 무엇일까?
- 나는 최근 MVI 패턴의 매력에 푹 빠졌다.
- 순수 함수 기반의 사이클을 가지는 MVI의 장점덕에 코드 흐름을 파악하기 좋기 때문이다.
- MVI에 기반하여 MVI의 구성 요소들을 직접 구현해보자

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파일 분리가 엄청 많이 되어있어서 궁금했는데 MVI패턴이라군거군요. 덕분에 새로운 패턴 알아갑니다..! 찾아보니 안드로이드에서 필요해서 나온거였군요!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants