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

[부나] 3, 4단계 오목 제출합니다. #32

Merged
merged 29 commits into from
Mar 27, 2023

Conversation

tmdgh1592
Copy link
Member

1, 2단계 커밋이 포함되어 있어서 제외하고 다시 PR을 보냅니다!

Copy link

@galcyurio galcyurio left a comment

Choose a reason for hiding this comment

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

3, 4단계 미션 구현 고생하셨습니다 👏👏
현재 Activity에 domain, data, ui 코드가 모두 섞여있습니다.
안드로이드에서도 이전처럼 MVC 패턴으로 구현해보세요.

app/src/main/AndroidManifest.xml Outdated Show resolved Hide resolved
app/src/main/res/layout/activity_game_result.xml Outdated Show resolved Hide resolved
Comment on lines 57 to 71
private fun continuePreviousGame() {
omokRepo.getAll {
if (it.count % 2 == 1) toggleTurnHolder(StoneColorModel.BLACK)
while (it.moveToNext()) {
val col = it.getInt(it.getColumnIndexOrThrow("x"))
val row = it.getInt(it.getColumnIndexOrThrow("y"))
val index = row * Omok.OMOK_BOARD_SIZE + col
val omokIv: ImageView = boardImageViews()[index]
val putResult = omok.put { Point(row, col) }
if (putResult is PutSuccess) {
drawStoneOnBoard(omokIv, putResult.stoneColor)
}
}
}
}

Choose a reason for hiding this comment

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

UI layer에 ui, domain, data 코드가 모두 섞인 스파게티 코드입니다.
아래와 같은 순서로 개선해보세요.

  1. MainActivity에서 InputView와 OutputView를 구현하도록 만들어보세요.
  2. OmokController에서 OmokInputView, OmokOutputView가 아닌 InputView, OutputView interface에 의존하도록 만들어보세요.
  3. MainActivity에서 Controller를 사용하도록 만드세요.

@tmdgh1592
Copy link
Member Author

tmdgh1592 commented Mar 26, 2023

안녕하세요 토리!
말씀해주신 피드백과 DM으로 여쭤봤던 내용을 기반으로 코드를 수정해보았습니다.
우선, Coroutine을 사용하여 takeTurn을 하는 동안 block 하도록 하였습니다.
또한 Activity가 domain, data 관련 코드를 가지고 있어 스파게티 코드로 이어지던 문제를 해결해보고자 하였습니다.

최대한 고민하며 코드를 작성했는데, 보시기에 DM으로 제안해주신 방향과 다르거나 미숙한 부분이 많을 것으로 생각�됩니다. 🥲
따끔한 지적과 조언을 해주시면 정말 많은 도움이 될 것 같습니다.
감사합니다!

Copy link

@galcyurio galcyurio left a comment

Choose a reason for hiding this comment

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

피드백 반영이 힘들었을텐데 굉장히 잘 해주셨어요. 👍️
코루틴을 쓰셔서 관련된 피드백도 드렸는데 반드시 반영하실 필요는 없습니다.

app/build.gradle.kts Show resolved Hide resolved
import repository.Repository

class AndroidOmokController(
private val controller: ConsoleOmokController,

Choose a reason for hiding this comment

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

같은 layer 끼리 서로 의존성을 가지지 않아야 합니다.
공통되는 로직이 있다면 해당 로직만 별도 객체로 분리해주세요.

Copy link
Member Author

Choose a reason for hiding this comment

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

템플릿 메서드를 사용하여 공통되는 로직을 상위 클래스로 옮기고, 변경이 필요한 로직에 대해서는 별도의 서브 클래스에서 구현하도록 변경하였습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

앗.. 지금 리뷰를 다시 읽어 봤는데 공통되는 기능을 하나의 클래스로 분리해서 컴포지션하기를 의도하신 걸까요?!

Choose a reason for hiding this comment

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

네, Composition을 의도했지만 상속을 통한 재사용도 좋습니다!

app/src/main/java/woowacourse/omok/view/OmokInputView.kt Outdated Show resolved Hide resolved
app/src/main/java/woowacourse/omok/view/OutputView.kt Outdated Show resolved Hide resolved
Copy link

@galcyurio galcyurio left a comment

Choose a reason for hiding this comment

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

피드백 잘 반영해주셨네요 👏
코루틴까지 적용하는 건 많이 힘들었을텐데 잘 적용해주셨네요 👍
지금까지 오목 미션 고생하셨습니다!

print(ASK_POSITION_MESSAGE)
val colRow = readln()
if (colRow.length !in POSITION_INPUT_RANGE) {
println(INVALID_FORMAT_ERROR_MESSAGE)
readPosition(onPutStone)
CoroutineScope(Dispatchers.Main).launch { readPosition() }

Choose a reason for hiding this comment

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

suspend fun이므로 호출자의 CoroutineScope을 사용하면 되어서 새롭게 CoroutineScope을 만들지 않아도 됩니다.

import repository.Repository

class AndroidOmokController(
private val controller: ConsoleOmokController,

Choose a reason for hiding this comment

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

네, Composition을 의도했지만 상속을 통한 재사용도 좋습니다!

@galcyurio galcyurio merged commit a763b5b into woowacourse:tmdgh1592 Mar 27, 2023
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.

3 participants