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

[자동차 경주] 육새라 미션 제출합니다. #1462

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

Conversation

saera-yook
Copy link

@saera-yook saera-yook commented Oct 28, 2024

중점적으로 시도한 것

  1. 효율적인 관리를 위한 패키지 분리 시도

    특정 패턴을 따랐다고 하기에는 부족한 부분이 많지만 굳이 따지자면 MVC 패턴에 가까운 것 같습니다.
    데이터베이스, 레포지토리 개념에 대한 이해가 부족해서 관련된 부분은 제외하고, 아래 5가지 패키지로 분리해 보았습니다.

    - config: 프로그램 초기 실행 설정 관리.
    - view: 콘솔 입출력 관련 기능 및 상수 관리.
    - controller: view와 model(service)을 연결하는 매개체. 데이터를 각 객체가 사용할 수 있는 형태로 처리하여 전달.
    - service: model과 controller 사이의 layer. 도메인 객체와 데이터를 생성 및 검증하고 비즈니스 로직을 처리.
    - model: 도메인 로직과 데이터 검증 및 관리.
    
  2. 일급 컬렉션 사용

    💡 장점
      1. 비즈니스 로직에 맞는 특정 자료 구조를 만들 수 있다.
      2. 불변성을 확보할 수 있다.
      3. 상태와 행위를 한 곳에서 관리할 수 있다.
    

    위의 장점을 활용해보고 싶어서 Racers 클래스를 일급 컬렉션으로 구현했습니다.

    • List<Car> cars 외 다른 필드는 존재하지 않음.
    • 최소 2개 이상, 중복된 이름이 없는 Car 객체들만 가능한 자료구조를 만듦.
    • 컬렉션을 변경할 수 있는 메서드가 없으므로 불변을 보장.
    • 컬렉션에 속한 객체의 상태 변경 및 데이터 조회는 모두 Racers 내에서 처리.
  3. 커밋 메시지 작성

    1주차 피드백 공유 문서를 참고하여 커밋 메시지를 의미 있게 작성한다.

    • 메시지 제목은 최대한 컴팩트하게 변경 사항과 이유를 명령문으로 작성
    • 메시지 본문에 변경된 파일과 변경 내용을 명시

아쉬운 부분

  • AppConfig에서는 controller나 service 객체까지만 생성하고 나머지 비즈니스 로직은 service와 controller 객체가 처리해야 한다.
    따라서 AppConfig의 아래 기능들은 CarRacingService의 역할에 해당하므로 책임 이동이 필요하다.

    • 도메인 객체 생성 기능: racingRule(), racers(), totalRounds(), carRacing()
    • 전체 비즈니스 로직 처리 기능: run()
  • RacingRule에서 랜덤값 생성 기능을 분리하고, 생성된 랜덤값 검증 기능만 담당하는 것이 좋겠다. 이유는 아래와 같다.

    • Randomsprivate 함수 내에서 호출되어 기능 테스트가 불가능하다.
    • 도메인 객체는 동일한 입력에 대해 항상 동일한 출력을 보장하는 것이 좋다.
      하지만 Randoms를 내부에서 사용함으로써 이에 대한 테스트와 결과값 보장이 불가능하다.
  • Car가 입출력과 관련된 로직을 모르는 것이 좋기 때문에 getStatus()가 완성된 문자열이 아닌 데이터만 전달할 수 있도록 해야한다.

  • Car.moveForwardIf()의 반환값은 테스트를 위해서만 사용되므로 값을 반환하지 않아도 된다.

  • CarRacing 클래스가 필요했을까? CarRacingServiceRacersRacingRule을 참조하여 처리할 수 있지 않았을까?

* InputValidator.java: 정규표현식을 잘못 사용한 부분을 고침
* InputValidatorTest.java: checkHasNumberOnly() 기능 테스트 추가
* ViewConstants.java:
  - 시도 횟수 입력값이 갖춰야 할 조건의 정규표현식을 상수로 선언
  - 상수를 사용 목적에 따라 구분하여 선언 순서를 개선
* InputController.java: 입력값을 변환하는 메서드들을 구현
* InputValidator.java: 변경된 로직에 맞는 파라미터 자료형 적용
* Application.java: 분리된 역할에 따라 작동하도록 코드 수정
* Move.java: 이동에 관련된 책임을 모두 갖도록 isPossible() 추가
* NumberValidator.java: 불필요한 클래스라 삭제됨
* Application.java: 책임 재분배에 따라 작동하도록 코드 수정
* InputValidator.java: 이름을 2개 미만으로 입력하면 예외 발생하도록 수정
* InputController.java: 문자열 분리 후 이름 개수 검증하도록 순서 변경
* ViewConstants.java: 이름 개수 에러 메시지 내용에 맞게 상수 이름 변경
* README.md: 기능 설명하는 내용을 의도에 맞게 수정
* Car.java: 이름이 null이거나 공백 문자만 있어도 예외 발생하게 수정
* CarTest.java: validateLengthOf()의 테스트 추가
* RacingConstants.java: 이름의 최소 길이를 나타내는 상수 선언 추가
* ViewConstants.java: 이름 길이 에러 메시지에 최소 길이 기준 추가
* README.md: 기능 설명하는 내용을 의도에 맞게 수정
* 불필요한 클래스 삭제
  - Judge.java, CurrentCar.java, NumberValidatorTest.java
* 자동차의 상태를 변경하거나 조회하는 기능 추가
  - Car.java, Racers.java
* 책임 재분배에 따른 코드 수정
  - Application.java, Racing.java, Move.java, OutputView.java
* 상수 추가 및 선언 순서 개선
  - ViewConstants.java
* 숫자 생성 기능과 이동 가능 여부 검증하는 기능을 합침
  - Move.java, NumberGenerator.java => RacingRule.java
* 책임 재분배에 따른 코드 수정
  - Application.java, Racing.java, Racers.java
* 불필요한 클래스 삭제
  - NumberGeneratorTest.java
* Application.java: 앱을 시작하고 끝내는 역할만 하도록 수정
* AppConfig.java: 앱에 필요한 객체들을 구성
* RacingInitializer.java: 게임에 필요한 초기값 등록
* CarRacing.java: 게임을 시작하고 끝내는 메서드 추가
* config:
  - AppConfig.java
  - InputValidator.java
  - RacingInitializer.java
  - RacingConstants.java
* controller:
  - InputController.java
* service:
  - Car.java
  - CarRacing.java
  - Racers.java
  - RacingRule.java
* view:
  - InputView.java
  - OutputView.java
  - ViewConstants.java
* CarRacing.java: 인스턴스 변수 선언 순서 및 생성자 파라미터 순서 변경
* AppConfig.java: 변경에 따른 코드 수정
Copy link

@SeongUk52 SeongUk52 left a comment

Choose a reason for hiding this comment

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

늦게마나 리뷰 남깁니다 2, 3주차 미션 모두 고생많으셨어요

@@ -0,0 +1,14 @@
package racingcar.model;

public class RacingConstants {

Choose a reason for hiding this comment

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

해당 클래스는 모델 계층이 아니기 때문에 패키지를 바꾸시던지 클래스 명에 어떤 모델에 대한 상수인지 표시해주시면 좋다고 생각합니다.

Comment on lines +13 to +15
public InputView inputView() {
return new InputView();
}

Choose a reason for hiding this comment

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

호출할 때 마다 인스턴스를 새로 생성하는데 매번 새로운 인스턴스를 만드는게 좋은 설계인지 고민을 해보셨으면 좋겠습니다.
그리고 메서드 이름을 좀 더 명확하게 해주시면 좋을 것 같습니다.


import java.util.List;

public class Racers {

Choose a reason for hiding this comment

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

현재 Racers라는 클래스가 가진 역할이 이름과 어떤 연관이 있는지 잘 모르겠습니다.

Copy link
Author

Choose a reason for hiding this comment

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

'경주에 참여하는 자동차들'이라는 의미로 네이밍했는데 잘 전달되지 않았던 것 같네요! 다음에는 더 좋은 이름을 고민해볼게요 :)


public void printWinners(List<String> winnerNames) {
String winners = String.join(NAME_DELIMITER + WHITE_SPACE, winnerNames);
System.out.printf("%s%s", WINNER_IS, winners);

Choose a reason for hiding this comment

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

중요한건 아니지만

Suggested change
System.out.printf("%s%s", WINNER_IS, winners);
System.out.printf(WINNER_IS + winners);

와 같이 작성하는 방법도 있습니다.

Comment on lines +29 to +43
public CarRacingService carRacingService() {
return new CarRacingService();
}

public RacingRule racingRule() {
return carRacingService().setRacingRule();
}

public Racers racers() {
return carRacingService().registerRacers(carRacingController().extractCarNames());
}

public int totalRounds() {
return carRacingService().registerTotalRounds(carRacingController().convertToNumber());
}

Choose a reason for hiding this comment

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

CarRacingService의 인스턴스가 매번 새로 생성되어 비효율적이라고 생각됩니다.

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.

2 participants