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);
}
- 명시적인 변수명, 함수명, 클래스명 작성하도록 처리
- https://www.thesaurus.com/ : 하나의 단어에 대한 유의어를 검색 할 수 있는 사이트
- https://grep.app/search : 단어로 git에서 Star를 많이 받은 오픈소스를 검색해볼 수 있는 사이트
- https://www.curioustore.com/#!/ : 변수명 검색 가능 사이트
- 함수형 인터페이스 및 람다 사용.
//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 을 할 수 있지 않을까?
- 전략패턴을 학습 및 적용해보면서 코드가 좀 더 이뻐지는 느낌을 받음
- 테스트 코드 작성에도 신경을 많이 써야할 것 같음
- 스트림, 람다를 의식적으로 많이 쓰도록 하자!
회고
: 코딩을 하다보면 나도 모르게 익숙하고 편한 방법(레거시를 만들어내는) 하게 된다. 의식적인 코딩을 통해서 좀더 나은 코딩을 하도록 노력하자.
: 이유없는 코드라인은 만들지 않도록 하자.
'MyStory > dev_life' 카테고리의 다른 글
동시성 이슈를 고려해서 쿠폰 발급하기 (Redisson을 활용한 분산 락 처리) (0) | 2023.02.19 |
---|---|
우아한 테크 캠프 프로 5주차 회고 - 1 (0) | 2021.03.14 |
우아한 테크 캠프 프로 4주차 회고 (0) | 2021.03.07 |
우아한 테크 캠프 PRO 3주차 회고 (0) | 2021.02.14 |
우아한 테크 캠프 PRO 1주차 회고 (0) | 2021.02.04 |