[WIL] 2025-01-10_2-3주차_과제1

Yuri·2025년 1월 10일

WIL

목록 보기
2/4
post-thumbnail

✏️ 과제1 계산기 과제 해설 세션 후 개인 회고를 작성합니다.

분명 혼자 볼 때는 보이지 않던 부분도 다른 사람의 시각으로 보면 보이는 것처럼 해설 강의를 듣고 코드를 다시 보니 이상하게 짠 부분이 많다.
요구 사항 중 사소한 부분이라도 놓친 게 없는지 변수의 명명도 타인이 봤을 때 이해가 잘 되는지 생각해 봐야 할 부분인 것 같다.

강의 노트

  • Null-Safe한 코드
    Scanner로 입력받은 문자열은 null 이 될 수 없다.
    입력값을 비교할 때는 문제가 없었으나 이후 값을 비교하는 로직에서NullPointerException이 발생할 수 있으니 null 이 절대로 될 수 없는 쪽을 주체로 쓰자 (Secure Coding)
"exit".equals(sc.nextLine()); // "exit"는 절대 null 이 될 수 없다.
  • ArrayList의 toString() 생략
    ArrayList의 참조변수를 직접 System.out.println() 에 출력해도 리스트의 전체 요소를 출력한다 → toString()으로 재정의하지 않아도 참조값을 출력하지 않는다.
    이는 ArrayList 가 상속받은 AbstractCollection에 오버라이딩 되어있다.

    이 컬렉션의 문자열 표현을 반환합니다. 문자열 표현은 컬렉션의 요소들이 반복자에 의해 반환되는 순서대로 나열된 목록으로 구성되며, 이는 대괄호("[]")로 둘러싸여 있습니다. 인접한 요소들은 문자 ", "(콤마 및 공백)로 구분됩니다. 요소들은 String.valueOf(객체)에 의해 문자열로 변환됩니다.

  • Generic 타입 이레이저
    컴파일 이전 코드에서는 <?> Generic이 존재하지만 컴파일 이후 런타임 소스에서는 <?> 을 없앤다. → Raw Type
    : 제네릭은 자바 1.5에 도입되어 제네릭이 없는 기존 코드도 제대로 컴파일이 되어야하고 제네릭을 넣은 신규 코드도 컴파일이 되어야한다. 이를 고려하여 자바에서 런타임에 코드에서 Generic을 없애버린다.

→ 타입 이레이저를 극복하고 제네릭 클래스 사용하기

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        ArithmeticCalculator<BigDecimal> calculator = new ArithmeticCalculator<>(BigDecimal.class);
        // ...
}
public class ArithmeticCalculator<T extends Number> {

    private final List<T> resultList = new ArrayList<>();
    private final Class<T> type;

    public ArithmeticCalculator(Class<T> type) {
        this.type = type;
    }

    public T calculate(T firstNumber, T secondNumber, Operator operator) {
        T result = operator.apply(firstNumber, secondNumber, type);
        addResult(result);
        return result;
    }
}
  • stream()
    for vs stream
    for문의 성능이 훨씬 좋다. (stream의 경우 내부에서 객체 생성과 삭제가 빈번하게 일어나기 때문이다.) 하지만, 가독성적인 측면에서 stream이 이해가 잘되기 때문에 stream을 많이 사용한다.
    무분별한 stream은 성능 저하로 이뤄지기 때문에 케이스에 따라 trade-off(하나를 얻으면 하나를 잃는 상충관계)한 의사결정이 필요하다.

➕) Collection 인스턴스는 바로 stream을 탈 준비가 되어 있다.

collect.stream()
       .filter(e -> e.doubleValue() > 0.0)
       .toList(); // toList(): 결과는 list로 반환받는다.

하지만, 배열의 경우 바로 stream을 탈 수 없다.

Arrays.stream(arr)
      .filter(a -> a.doubleValue() > 0.0)
      .toList();

회고

배운 점(Keep)

  • IDE가 경고를 띄워주면 다시 한번 생각해보자
    • 개발자보다 똑똑한 IDE가 챙겨주는 디테일은 좋은 코드를 만든다.
  • 주석으로 적지 않고 코드로 의도를 알 수 있게 하자
    • 주석이 모든것을 해결해 주지 않는다. 가져다 쓰는 개발자는 잘못이 없다. 제공하는 개발자가 제약을 걸지 않았다면 제공하는 쪽의 문제이다. 코드를 작성할 때 제공하는 개발자의 마음으로 문제가 될 수 있는 부분은 미리 막아야 한다.

아쉬운 점(Problem)

  • 요구사항에서 놓친 부분이 없는지 검토
    • 과제 요구사항을 여러 번 읽고 TIL도 작성했지만 요구사항에서 놓친 부분이 있다.
    1. 과제 Lv1 양의 정수만 입력받기: int형으로 선언하면 - 값도 입력 받을 수 있다.
      → 이 부분은 심지어 TIL에서 언급도 했으나 제약이 빠져있다! 사소한 부분이라도 디테일을 챙겨야 한다.
    2. 연산의 결과값은 Double로 받기
      → 별도의 제약은 없었으나 나눗셈의 경우 반환 타입이 int면 소수점 값이 유실된다. 코딩하면서 고민했던 부분이지만 제약이 없으니 수정하지 않았다. 요구사항에서도 당연한 부분이라 굳이 언급하지 않았던 것일 수도...
  • 변수명 등 코드가 직관적이고 이해하기 쉽게 작성되었는 지 검토
    • 과제 평가기준 중 하나이다. 앞으로 다른 사람과 협업을 할 때 내 코드가 이해하기 쉬운 이름으로 되어있는지, 코드 컨벤션을 잘 따르고 있는지 확인할 필요가 있다.

놓친 요구사항은 Lv1, Lv2를 구현하면서 챙기지 못한 부분이라 해설 강의를 들으며 아차 싶었다. 고난이도 도전과제의 완성도를 챙기는 것도 좋지만 기본 과제에도 충실했으면 더 좋았을 것 같다.

개선할 점(Try)

  • 과제 제출은 끝났지만 공부는 끝나지 않았다

    • 해설 강의와 이후 코드 리뷰에서 내 코드의 문제점을 평가받고 직접 개선하면서 더 좋은 코드로 만들자.
  • 코드 리뷰 후 개선점 ✨

    • Scanner 를 통한 사용자 입력에서 nextLine()으로 잘 안될 때 next()로 처리하기
      → ➕) Scanner 를 사용한 콘솔 입력은 사실 웹 개발에 들어가면 사용하지 않지만 코딩 테스트 등에서 많이 사용하니 유의하자.
profile
안녕하세요 :)

0개의 댓글