2주 차 강의 내용 정리

  • TDD, 클린코드
  • 1주차미션(racingCar) 대한 피드백 & 라이브 코딩

Clean Code 가이드

의미 있는 이름

  • 의도를 분명히 한 naming 규칙
    • 협업할 때 새롭게 코드를 볼 사람을 생각해서 더 나은 이름으로 작성하기
    • 주석을 사용하지 않아도 될 정도로 분명하게 naming 하기
// 잘못된 변수 사용
int d; // 경과시간(day)
  • 의미 있게 구분하기
    • 기준을 세우고 네이밍하는 것이 좋다. (ex. 카멜케이스, 스네이크케이스 등)
  • 인터페이스 클래스와 구현 클래스
    • 인터페이스는 공통적인 개념으로 naming하고, 구현 클래스는 의도가 드러날 수 있는 구체적인 naming을 사용하라
  • 클래스 이름
    • 명사, 명사구가 적합
    • Manager, Processer, Data, Info 등과 같은 단어는 피하고, 동사는 사용하지 않는다.
  • 메소드 이름
    • 동사, 동사구가 적합
    • 접근자, 변경자, 조건자에는 값 앞에 get, set, is를 붙인다.
    • 생성자를 중복해서 정의할 땐 정적팩토리 메소드를 사용. 메소드명은 인수를 설명하는 이름으로 사용한다.

경계

wrapper 클래스를 사용

Map, List 같은 collection 등 외부에 노출하는 경우 많은 인터페이스가 노출하게 되기 때문에 wrapper 클래스를 사용해서 숨기는 것이 좋다.

  • 사용자에게 모든 인터페이스를 노출하지 않아도 된다.
  • 내부적인 변경이 발생하더라도 외부 변경은 발생하지 않는다.
Map<Integer, Sensor> sensors = new HashMap<>();
Sensor s = sensors.get(sensorId);
public class Sensors {
    Map<Integer, Sensor> sensors = new HashMap<>();

    pubilc Sensor getById(String id) {
        return sensors.get(id);
    }
}

=> Map을 사용자에게 직접 노출하지 않고 Sensors 클래스르 이용해서 처리 가능하다.

1주차 미션에 대한 피드백

  • 로직이 동일한 테스트일 경우 @ParameterizedTest 를 활용해서 하나로 합칠 수 있다. 
    @ParameterizedTest
    @CsvSource({"20 + 10,30","20 - 10,10","20 * 10,200","20 / 10,2"})
    @DisplayName("사칙연산 test")
    void calculationTest(String inputData, Long result) {
        expression = new Expression(inputData);
        calculator = new Calculator(expression);
        Long testResult = calculator.calculate();
        assertThat(testResult).isEqualTo(result);
    }

 

 

  • 함수형 인터페이스 및 람다 사용.
//AS-IS
private static List<Car> mapCars(int carNums) {
        List<Car> cars = new ArrayList<>();
        for (int i = 0; i < carNums; i++) {
            cars.add(new Car());
        }
        return cars;
    }
//TO-BE
this.cars = Arrays.stream(splitCarNames(carNames)).map(name -> new Car(name)).collect(Collectors.toList());

 

  • 전략패턴 사용
    => 자동차가 움직이는 규칙을 독립시킬 수 있다. 규칙이 독립되면 테스트도 용의해진다. 
public interface MoveStrategy {
    boolean isMove(int value);
}

=> 이동 규칙 관련 인터페이스를 생성

 

public class RandomMoveStrategy implements MoveStrategy {
    private static final int START_CONDITION = 4;
    private static final int END_CONDITION = 9;

    @Override
    public boolean isMove(int value) {
        if(value >= START_CONDITION && value <= END_CONDITION) {
            return true;
        }
        return false;
    }
}

=> 인터페이스를 구현한 실제 적용할 규칙 클래스를 생성

 

public class Racing {
    private List<Car> cars;
    private MoveStrategy moveStrategy;

    public Racing(String carNames) {
        this.cars = Arrays.stream(splitCarNames(carNames)).map(name -> new Car(name)).collect(Collectors.toList());
        this.moveStrategy = new RandomMoveStrategy();
    }

    public void race() {
        for (Car car : cars) {
            car.racing(RacingCarUtils.randomValueGenerator(), moveStrategy);
        }
    }
}

=> 로직에 적용

 

2주차미션(racing-car) 리뷰

소스코드: github.com/louisJu/java-racingcar-ex

 

느낀 점

  • 변수명 결정하는데 시간이 오래 걸렸음. 위에서 언급한 사이트들을 이용한다면 조금 빠르게 naming 을 할 수 있지 않을까?
  • 전략패턴을 학습 및 적용해보면서 코드가 좀 더 이뻐지는 느낌을 받음
  • 테스트 코드 작성에도 신경을 많이 써야할 것 같음
  • 스트림, 람다를 의식적으로 많이 쓰도록 하자!

회고 

 : 코딩을 하다보면 나도 모르게 익숙하고 편한 방법(레거시를 만들어내는) 하게 된다. 의식적인 코딩을 통해서 좀더 나은 코딩을 하도록 노력하자. 
: 이유없는 코드라인은 만들지 않도록 하자.

+ Recent posts