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

1주차 미션 / 서버 4조 김광일 #1

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

Conversation

kamothi
Copy link

@kamothi kamothi commented Mar 19, 2024

안녕하세요 1주차 미션을 수행한 캬모치입니다.
이번 미션을 수행하며 객체지향이 무엇인가 다시 생각해볼 수 있는 시간이였던 것 같습니다. 간단하게 리팩토링 한 부분에 대해 설명 드리겠습니다.

  • Ladder에 역할을 분리
    현재 Ladder에는 사다리 생성, 사다리 타기, 게임 실행과 같이 여러 역할들이 존재하였습니다. 해당 부분은 단일 책임원칙에 맞지 않다 판단하여 역할들을 LadderCreator, LadderRunner, LadderGame과 같이 분리하였습니다.
  • 일급 컬렉션 사용, 원시값 래핑
    체지향 생활체조 원칙에 맞게 최대한 리팩토링 할려고 노력했지만 아직 부족한 부분이 많은거 같습니다.
  • 사다리 출력
    해당 사다리 출력을 위하여 LadderRunner에서 사다리를 타며 출력할 수 있게 구현해두었습니다.
  • view 모델 생성
    입출력에 해당하는 것들을 view에 정리하여 모아 두었습니다. 정확히 어느 부분까지 입력을 받아 출력을 해야할지 명확하지 않아 부족한 부분이 많은거 같습니다.
  • 패키지 분리

이번 미션을 수행하며 어려웠던 부분이 몇가지 있었던 것 같습니다.

  1. 함수들이나 변수들의 이름을 어떻게 정의하는 것이 명확할까
  2. 좋은 테스트란 무엇일까?. 단순히 커버리지를 높이는 것인가? 아직 테스트라는게 매우 어렵게 느껴지더군요
  3. 역할과 책임의 분리는 어디까지 분리해야하는가. 아직 단일 책임 원칙이 어렵네요 ㅠㅠ

피드백을 적극 반영하여 다시 리팩토링 해보도록 하겠습니다. 감사합니다!

Copy link

@kmw10693 kmw10693 left a comment

Choose a reason for hiding this comment

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

1주차 코드 작성하느라 수고하셨습니다!
코드를 리뷰 하면서 단일 책임 원칙을 어떻게 고려할지, 클래스를 어떻게 분리할지 많은 고려가 담긴 코드로 보입니다.
정말 수고하셨습니다! 제가 정말 많이 부족하지만 최대한 코드 리뷰를 해보았습니다. 감사합니다.

import java.util.List;

public class CustomLadderCreator implements LadderCreator{
Row[] rows;

Choose a reason for hiding this comment

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

외부 클래스에서 rows 필드에 직접적으로 접근 가능하므로, 접근 제어자를 private final으로 설정하는 것이 나아보입니다. final로 설정하여, 필드에 인스턴스 재할당을 막아줄수 있습니다.

public class CustomLadderCreator implements LadderCreator{
Row[] rows;
public CustomLadderCreator(LadderSize ladderSize) {
ladderSize.validate();

Choose a reason for hiding this comment

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

생성자에서 ladderSize.validate() 메서드를 실행하는 것보다, ladderSize 객체 내부에서 생성자나 팩터리 메서드를 통해 인스턴스가 생성될때, 내부에서 검증하는 것이 나아보입니다. 프리미티브 타입을 객체화 할때 장점은, 예외 처리를 내부적으로 실행할 수 있는 장점을 갖고 있습니다.


import ladder.model.Row;

public interface LadderCreator {

Choose a reason for hiding this comment

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

공통적인 로직을 갖는 메서드를 인터페이스로 분리해놓은 코드는 좋은 코드 인 것 같습니다!

import java.util.Random;

public class RandomLadderCreator implements LadderCreator{
Row[] rows;

Choose a reason for hiding this comment

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

외부 클래스에서 rows 필드에 직접적으로 접근 가능하므로, 접근 제어자를 private final으로 설정하는 것이 나아보입니다. final로 설정하여, 필드에 인스턴스 재할당을 막아줄수 있습니다.

Row[] rows;

public RandomLadderCreator(LadderSize ladderSize) {
ladderSize.validate();

Choose a reason for hiding this comment

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

생성자에서 ladderSize.validate() 메서드를 실행하는 것보다, ladderSize 객체 내부에서 생성자나 팩터리 메서드를 통해 인스턴스가 생성될때, 내부에서 검증하는 것이 나아보입니다. 프리미티브 타입을 객체화 할때 장점은, 예외 처리를 내부적으로 실행할 수 있는 장점을 갖고 있습니다.



public void validate() {
if (numberOfRows < 1 || numberOfPerson < 1) {

Choose a reason for hiding this comment

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

if 문안에, 조건을 넣는 것보다, private 메서드로 분리하여 넣는 것이 나아보입니다.

Copy link
Author

Choose a reason for hiding this comment

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

구체적으로 어떤 의미인지 알 수 있을까요?

Comment on lines +6 to +8
private final int numberOfRows;
private final int numberOfPerson;

Choose a reason for hiding this comment

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

numberOfRows, numberOfPerson 필드는 프리미티브 타입이라, 의미적으로 맞는 프로그램을 작성하기 힘들어보입니다.
또한 두 필드 모두 0 초과의 조건을 가지므로, int 대신 NatrualNumber 클래스로 관리하는 것이 나아보입니다.

Comment on lines 16 to 22
public Position increment(){
return new Position(position+1);
}

public Position decrement(){
return new Position(position-1);
}

Choose a reason for hiding this comment

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

두 메서드 모두 new Position() 메서드를 호출하여, position이 정당한 값인지 예외처리가 불가능합니다. return fromValue() 를 호출하는 것이 적절하다 생각합니다.

Comment on lines +16 to +27
LadderSize ladderSize = new LadderSize(3, 5); // 예시로 5*4 크기의 사다리 생성
CustomLadderCreator ladderCreator = new CustomLadderCreator(ladderSize);

// When
Row[] rows = ladderCreator.getRows();

// Then
assertEquals(3, rows.length); // 행의 개수가 예상대로 생성되었는지 확인
for (Row row : rows) {
assertEquals(5, row.getSize()); // 각 행의 열의 개수가 예상대로 생성되었는지 확인
}
}

Choose a reason for hiding this comment

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

테스트 코드를 작성할떄, given when then을 사용하시는 것이 좋은 것 같습니다! 좋은 코드네요!

Comment on lines +17 to +20
Row[] rows = new Row[3];
for(int i = 0; i < 3; i++) {
rows[i] = new Row(3);
}

Choose a reason for hiding this comment

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

이 부분이 중복되어 @beforeeach 어노테이션을 가진 메서드를 이용하여, 단위 테스트 시작 전 공통으로 실행되는 로직을 갖는 것이 좋아보입니다.

@kamothi kamothi changed the title Kamothi 1주차 미션 / 서버 4조 김광일 Mar 20, 2024
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