프리코스 2주차를 진행하며

박세건·2023년 11월 2일
0

회고록

[당당하게 getter 사용]

정보 은닉을 위해 필드를 private로 숨겨놓고 Getter와 Setter를 사용한다면 정보 은닉의 효과를 볼 수 없기에 1주 차 때도 사용하지 않았고 2주 차 때도 마찬가지로 사용하지 않고 진행하기로 했습니다. 그렇기 위해서는 Tell, Don’t Ask(TDA) 원칙을 지키면서 코딩을 진행해야 했습니다. 두 개의 클래스 사이에서 TDA 원칙을 지키는 것은 어렵지 않았지만 3개 이상의 클래스 사이에서는 로직이 복잡해지고 너무 빙 돌아간다는 느낌을 받았습니다.
따라서 메서드의 개수도 많아지게 되었고 테스트하는 과정도 어려워졌습니다.
캡슐화도 지키고 싶고 로직도 효율적으로 구현하고 싶었기에 계속해서 고민하고 학습했습니다. 그러다가 요구사항이 ‘자동차의 이동 거리를 보여줘야 한다’는 내용이었다는 것을 생각했고 이 뜻은 이동 거리에 대한 캡슐화를 지킬 수 없는 것이 아닌가? 라고, 생각하게 되었습니다.
그렇다면 이동 거리를 나타내주는 필드에 대해서는 getter를 사용해도 무방한 것입니다.
이렇게 Getter가 사용되어야 하는 곳이 있기에 잘 판단해서 당당하게 사용해야겠다고 생각했고 후에 getter를 이용해서 이전보다 더 효율적이고 깔끔한 코드를 구현할 수 있게 되었습니다. 2주 차 진행 중에 가장 많은 시간을 투자하였지만, 가장 많은 것을 알게 되었던 뜻깊은 과정이었습니다.

[테스트 코드의 중복 제거]

기능을 구현하면서 그 기능에 맞는 테스트 코드를 작성하였습니다. 테스트 케이스를 하나씩 직접 생성해서 테스트했기 때문에 메서드의 길이가 길어지고 중복되는 부분이 너무 많이 존재했습니다. 그래서 이러한 경우를 해결할 방법은 없는지 학습하던 중 @ParameterizedTest 어노테이션이라는 것을 사용해서 하나의 테스트 방법에 여러 개의 파라미터에 대해서 테스트할 수 있다는 것을 알게 되었습니다. 이 어노테이션을 사용해서 리팩토링을 진행했고 테스트할 값들을 외부에서 불러오게 되니 메서드의 길이가 크게 줄어들었고 중복 또한 제거할 수 있어서 가독성이 크게 향상했습니다.

[나만의 규칙을 정하자]

2주 차 문제를 해결하면서 ‘어떻게 메서드를 구현할 것이고 어떤 객체를 사용해서 구현할지’와 같은 생각을 하며 오랜 시간을 사용했었습니다. 물론 이처럼 더 효율적인 방법은 없는지 생각하는 것은 나쁘지 않다고 생각합니다. 하지만 저의 문제는 코딩을 진행하지 않고 오랜 시간 동안 생각만 한다는 것입니다. 결국 이런 습관 때문에 시간에 쫓기게 되었고 초조한 마음은 코딩하는 과정을 더 힘들게 하였습니다. 그래서 저는,

  • 객체를 필드로 갖는 클래스는 정적 팩토리 메서드를 사용한다.
  • 요구사항에서 객체화 될 수 있는 것은 모두 포장하거나 일급 컬렉션으로 저장
  • 사용자에게 보여줘야 하는 내용에 대해서는 Getter 사용

등 과 같은 나만의 규칙을 정해서 생각하지 말고 따를 수 있게 한다면 코딩에 더 많은 시간을 사용할 수 있다는 것을 알게되었습니다.

[코드 리뷰의 중요성]

1주 차를 끝내고 처음으로 코드 리뷰를 작성하고 받아봤습니다. 처음으로 리뷰를 작성해 보는 것이라 설레기도 했지만, 리뷰한 내용이 틀린 내용이면 어떡하냐는 생각에 걱정되는 부분도 있었습니다. 하지만 저는 틀린 부분이 있다면 이 리뷰를 통해서 학습하게 되는 계기가 된다고 생각하고 마구마구 리뷰하기 시작했습니다. 리뷰를 받은 부분에 대해서 학습하면서 성장하는 것으로 알고 있었는데 신기하게도 저는 리뷰를 달면서 더 학습하게 되었습니다. 혼자 코딩할 때는 놓쳤던 부분을 다른 사람의 코드를 보면서 알게 되었던 점이 많았고 코드 내용에 대해 서로 토론하는 활동도 너무 많은 도움이 되었습니다. 어느 순간 코드 리뷰에 재미를 느끼고 흥미가 붙어버린 저는 리뷰 스터디를 만들어서 성장하고 있습니다.

[일급 컬렉션]

1주 차를 진행할 때는 List> names처럼 사용했던 코드에 일급 컬렉션으로 포장해 보면 어떠냐는 리뷰를 받았고 일급 컬렉션을 학습해야겠다고 생각했습니다. 알고 보니 객체지향 생활체조에서 권장하는 내용이었고 ‘비즈니스의 종속적인 자료구조’, ‘불변성 보장’, ‘상태와 행위를 한 곳에서 관리’, ‘이름있는 자료구조’ 등의 장점을 갖고 있다는 것을 알게 되었습니다.
‘이름있는 자료구조’를 생성할 수 있다는 장점을 이용해서 이번 미션에 적용하였고 이전보다 가독성을 향상하게 시킬 수 있었습니다. 아직 일급 컬렉션 사용에 대해 부족함을 느꼈고 확실하게 학습해서 3주 차 미션에는 일급 컬렉션의 다양한 장점들을 적용해 봐야겠다고 생각했습니다.

[정적 팩토리 메서드]

다른 분들의 코드를 리뷰하던 중 문득 of, from 함수가 많은 사람들에게서 사용되고 있다는 것을 알게 되었습니다. 그러던 중 1주 차 코드 부분에서 가지고 오는 인자에 따라서 다르게 생성시키는 생성자를 구현했던 부분에 대해 정적 팩토리 메서드를 사용해 보라는 리뷰를 받았습니다. 학습하던 중에 많은 분들이 사용했던 of, from 함수가 정적 팩토리 메서드를 의미하는 것이라는 것을 알게 되었습니다.

  • 이름을 가질 수 있다.
  • 호출할 때마다 새로운 객체를 생성할 필요가 없다.
  • 하위 자료형 객체를 반환할 수 있다.
  • 객체 생성을 캡슐화할 수 있다.

와 같은 장점들에 대해서 배울 수 있었고, 이번 미션을 진행하면서 생성자 대신에 정적 팩토리 메서드를 사용해서 이름을 지정해 주었고 new()를 사용했을 때보다 향상된 가독성을 경험할 수 있었습니다.

1주차 공통 피드백에서 확인할 것

  • 커밋 메시지를 의미 있게 작성
    커밋 메시지를 보고 작업한 내용을 이해할 수 있도록 작성

  • Git을 통해 관리할 자원에 대해서도 고려
    굳이 git으로 관리하지 않아도 되는 파일이 존재할 수 있기에 확인

  • 이름을 통해 정확한 의도를 드러내자
    나 자신, 다른 개발자와의 소통을 위해 가장 중요한 활동 중의 하나가 좋은 이름 짓기이다. 변수 이름, 함수(메서드) 이름, 클래스 이름을 짓는데 시간을 투자하라.

  • 축약하지 않는다
    네이밍이 길어진다고 해서 축약을 하게되면 혼란을 야기할 수 있다.
    하지만 예를 들어서 Order라는 클래스에 shipOrder 메서드 이름은 필요가 없다 ship이라고 작성해도 order.ship()이라고 호출되기에 간결하게 가능하다.

  • 공백도 코딩 컨벤션
    if, for, while문 사이의 공백도 코딩 컨벤션이다.
    이부분은 조금 더 공부가 필요한 부분같다.
    확실히 이해하고 넘어가자

  • 의미 없는 주석을 달지 않는다
    주석으로 의미를 나타내기 보다는 네이밍을 통해서 의미를 전달할 수 있게 작성해보자

  • Java에서 제공하는 API를 적극 활용한다
    내가 현재 구현하고있는 기능이 Java API로 존재하지 않는지를 확인하고 구현한다.
    확인하고 없다면 구현한다.

중요 한점

  • 함수를 분리하고, 각 함수별로 테스트를 작성하는 것에 익숙해지는 것을 '목표'
  • 과제를 제출할 때 이번 주 차 '목표'를 중심으로 학습하면서 느낀 점을 소감문으로 작성해 주세요. 이때 학습한 '과정’을 잘 드러내 주세요.

1주차 코드 리뷰받은 내용

코드를 리뷰하면서 신기했던점은 평소에 코드를 작성할 때는 몰랐던 부분을 확인할 수 있었다. 예를 들어서 함수명이나 변수명, 클래스 명에서 의미를 파악해서 자연스럽게 이어지고 읽어지는지가 중요했고 이러한 것들이 가독성을 높여주는 요소가 된다고 생각하게되었다.
코딩능력과 리뷰는 다르다는 것을 알게되었다.

  • 가독성이 좋은 코드인지를 한눈에 볼 수 있었다
    내 코드를 내가 리뷰해보며 가독성이 좋은지 확인해보자
  • 코드의 흐름이 자연스러운지 확인할 수 있었다!
  • 굳이 필요없는 코드 작성
    static의 기능을 사용하지 않는데 추가
    -> 코드를 작성할때 필요한 부분인데 확인하고 작성하고 리팩토링 과정에서 다시 한번 확인하기
  • 서로 다른 역할을 하는 생성자
    정적 팩토리 메서드 방식 사용해보기(객체 생성에 이름을 붙여주는 방법?)

정적 팩토리 메서드란 객체 생성의 역할을 하는 클래스 메서드
생성자 대신 정적 팩토리 메서드를 고려하라

  • 매직 넘버 처리
    다른 사람이 읽었을때에 상수에 대한 내용을 이해할 수 없다면 처리를 해주는 것
    예시)
private static final String VALIDATE_LADDER_HEIGHT_MESSAGE = "사다리의 최소 높이는 1이상이어야 합니다.";

->

private static final int MINIMUM_LADDER_HEIGHT = 1;
private static final String VALIDATE_LADDER_HEIGHT_MESSAGE = "사다리의 최소 높이는 " + MINIMUM_LADDER_HEIGHT + " 이상이어야 합니다.";

-매직 리터럴 처리

System.out.println("3개의 숫자를 모두 맞히셨습니다! 게임 종료");

이런 부분을 3을 상수로 처리하고 나머지 부분을 message로 처리 후 합치는 방식 사용

문자열 또한 가독성을 힘들게 만들 수 있다. 상수로 처리해보자

  • Exeption 등의 메세지를 한곳에 모아보자
  • 메서드명 줄이기(길다면 기능이 많다는 것)
    Util 클래스로 일반화를 적용시켰지만 어떤것이 맞을까 PgmJun님에게 물어보자!
  • 변수명에 자료형의 이름을 사용하는 것은 좋은 습관이 아니다
    Validator과정에서 변수명을 String을 사용해서 나타내었는데 의미를 나타낼 수 있는 변수명으로 변경해보자
  • 생성자 주입을 사용하는 이유
  • 메서드 이름을 add 보다는 increase나 one 을 사용해보자

-조건문 중첩은 코드의 의도 파악 및 유지보수가 힘들고 가독성이 떨어진다

  • 하나의 클래스가 하나의 기능을 담당할 수 있도록

진행중 배운 것들

  • 입력에 대한 테스트

  • getter를 쓰지 않는것

  • this 의 용도

  • 코드 리뷰의 중요성

  • 클래스 정렬을 위한 Comparable

  • comparable, Comparator 차이
    comparable - 나와 상대를 비교
    comparator - 두 객체를 비교
    -dto와 엔티티 차이

  • getter, setter 최소한 줄이기
    객체에게 명령을 내린다

  • 스트림 알아보기
    Collection이나 조건에 사용해보자

  • 정적 팩토리 메서드
    객체 생성에 이름을 붙일 수 있다

  • Predicate란
    boolean값을 리턴하는 함수형 인터페이스
    람다로 접근가능

  • 클린코드 다시 공부

  • 일급 컬렉션으로 포장하기(불변성)

  • 리팩토링

  • Getter 를 쓰면 왜 안 되는가?
    캡슐화의 의미가 없어진다. private으로 필드를 선언해놓고 getter로 아무 곳에서나 값을 꺼내올 수 있다면 상태 정보가 그대로 노출되는데 private을 굳이 선언한 의미가 없어진다.

  • 입력을 받기위해 생성했던 CarNames가 나중에 다시 재사용되는 경우를 보았다!

  • "테스트를 위해 구현 설계가 변경될 수 있다.
    테스트 코드는 구현의 보조적인 수단이 아니며, 같은 레벨로 봐야한다.
    좋은 디자인으로 구현된 코드는 대부분 테스트 하기가 쉽다.
    테스트 하기 어렵게 구현 되었다면, 코드 확장성 / 의존성 등 코드 디자인, 설계가 잘못되었을 확률이 굉장히 높다."

  • 의존성 : 유지보수 시점에 같이 변환되는지 안되는지

  • 해당 요구조건이 변경 되었을때에 어디를 수정할 것인가! 을 생각해서 해당 기능이 어느 역할의 기능인지 판단

  • 주어진 요구조건이 내부의 속성을 밖으로 꺼내는 것이었기에 getter를 피해갈 수 없다!!!

    이미 요구사항이 은닉하지 말것을 요구하고 있다, 때문에 getter의 사용으로 캡슐화가 깨어졌다고 말하기 힘들다ㅏ!!!!
    분명하게 getter 사용해야 되는 곳이 있고,
    분명하게 사용해야 되는 곳이있다.
    아주 좋은 설명

  • 나만의 규칙을 정하는 것

  • 기능만 보고 구현하는 것이 아닌 기능을 보고 어떤 객체들이 필요할지를 생각한 후에 진행

  • 테스트의 중복을 줄이기위한 @ParameterizedTest 사용

  • 입출력 테스트

  • 디미터의 법칙
    무작정 .의 개수를 줄이는 것이 아닌 연속적으로 . 을 사용했을때의 내부구조가 드러나는 것을 막는 것이다.
    때문에 Stream같은 체이닝은 예외다.!

profile
멋있는 사람 - 일단 하자

0개의 댓글