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

[부산대 BE_정지민] 미션 제출합니다. #109

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

Conversation

stopmin
Copy link

@stopmin stopmin commented May 5, 2024

다들 수고하셨습니다 🔥🔥

PR이 조금 심심해서 구현하면서 고민했던 부분이랑, 미래의 누군가가... 제 코드를 리뷰한다면 조금 도움이 됐으면 해서 정리해봤습니다 :D

짜다보니 계속 부족한 부분이 보여서 계속 고치고싶네요.
다음 미션은... 가능하면... 빨리 시작해서 이틀~사흘 정도는 고민해서 더 좋은 코드 짜보겠습니다!!!!!
다들 다음미션도 파이팅합시다💪

코드 리뷰시 참고사항

1. Player 추상화

  • HumanPlayer, ComputerPlayer도 일종의 Player라고 판단하였고 동작이 Player라는 하나의 인터페이스로 정의될 수 있다고 판단하여 Player로 추상화하여 각자 HumanPlayer, ComputerPlayer로 구현체로 두었습니다.

2. 난수 생성 모듈

  • 난수를 생성하는 모듈도 클래스로 두었습니다. (이건 추상화 하기는 좀 에바인 것 같아서 뺐습니다. 언젠가 다른 라이브러리로 생성할 수도 있겠다고 생각했긴 했는데 너무 오바같네요.)

3. 입출력 핸들러

  • 입출력을 담당하는 부분은 일종의 infra계층, 도메인/어플리케이션의 외부에 맞닿아있는 부분이라고 판단하여 DB나 다른 ORM과 맞닿아있을 수 있는 infra계층에 두었습니다.
  • 근데 솔직히 common에 들어가는것도 나쁘지 않을 것 같네요!

4. 입/출력 메시지 및 에러 메시지

  • 각종 메시지들은 domain 내에서 Enum으로 관리하였습니다.
  • 특히, format() 메서드를 활용하면 Enum 내의 message에 각종 값들을 추가해줄 수 있습니다. 이를 통해서 게임 결과(스트라이크, 볼)의 개수도 유연하게 대처할 수 있었습니다.
  • 예외의 경우 message외에 ErrorType도 둘 수 있는걸로 아는데 (Illegal~~~Error같은 것들이나 뭐 404나..) 새벽감성으로 생각이 안나서 일단 message만 다루도록 했습니다.

5. 야구게임에 관련된 매직넘버들

  • 야구게임에 관련된 매직 넘버: 숫자의 개수, 최대숫자, 최소 숫자의 경우 const상수로 두었습니다.
  • 굳이 따지고 보면 Enum에 둘 수도 있다만 야구게임에 한정되었을뿐더러 굳이 뺄 필요가 없다고 생각하여 BaseballGame 도메인에서 관리하도록 하였습니다. 예외 문구나, 타 클래스에서 validation을 할 때도 해당 상수를 참고하도록 작성하였습니다.
    public static final int MIN_NUMBER = 1;
    public static final int MAX_NUMBER = 9;
    public static final int NUMBER_SIZE = 3;

6. GameService를 왜 별도로 두었는가?

  • 재시작 가능성이 있기 때문에 Game을 도메인으로 두고 GameService를 별도로 두었습니다.
  • 게임 자체에 재시작 기능이 있는 것은 뭔가 구조적으로 결함이 생기기 쉬운 구조라고 생각했습니다.
  • 왜냐하면 저번에 제가 야구게임을 한번 구현해봤을 때, 그렇게 구현할 경우 반복문이든 While문을 쓰든 stack이 쌓이도록 구현했던 기억이 있습니다.
  • 그래서 차라리 이걸 빼내어서 게임을 추상화하고, 게임 서비스를 별도로 두는게 유지보수성이 뛰어나다고 판단하였습니다.

7. 테스트코드를 위해서 원래 코드를 양보해도 되는가? - reflection
테스트코드에 대해서는 고민이 많았습니다.
굳이, private로서 동작해도 되는 것들이 테스트코드를 위해서 과연 public이나 protect같은 접근제어자로 바꿔도 될까? 고민하다가 테스트코드를 위해서 코드를 수정한다?라는 것은 솔직히 유지보수성은 좋다고 한들, 전체적인 코드 품질을 위해서는 조금 좋지 않을 수 있다고 판단하였습니다.

따라서 테스트코드에서 reflection를 활용하여 해당 메서드에 일시적으로 접근할 수 있도록 조작했습니다.
그런데 좋은 방법이라고 생각하진 않습니다.

예제코드는 아래와 같습니다 :D

  private static Method validateInputMethod;
  private final HumanPlayer humanPlayer = new HumanPlayer();

  @BeforeAll
  static void setUp() throws NoSuchMethodException {
      validateInputMethod = accessModifier("validateInput");
  }


  private static Method accessModifier(String methodName) throws NoSuchMethodException {
      Method method = HumanPlayer.class.getDeclaredMethod(methodName, String.class);
      method.setAccessible(true);
      return method;
  }

다른 선배한테 조언을 구해봤는데 객체로 빼서 public으로 여는 방법이 좋다고 하는데 다음 미션에서 한번 활용해보겠습니다 :D

stopmin added 30 commits May 5, 2024 22:24
- 유지보수를 위해서는 나누는게 맞지만 프로젝트가 작아서 합쳐둠.
- 재시도 가능성을 생각하여 게임 자체에 대한 서비스로직으로 게임 추상화
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.

None yet

1 participant