빌더패턴 글을 쓰기위해 다른분들의 글을 읽으면서 AccessLevel 이라는 키워드를 발견하게되었고 이와 빌더와의 관계를 공부하며 또한 빌더패턴을 사용했지만 정확하게 사용한방법을 알아본 결과를 코드로 리펙토링하게되었습니다.
추가적으로 팀원과의 협업작업중이므로 Checkstyle도 다운받아서 고치게되었습니다.
체크스타일이란?
체크스타일은 코드를 작성할 때 일반적으로 지켜야 하는 코딩 표준을 잘 준수할 수 있도록 지원하는 유틸입니다.
대표적인 예로 카멜케이스 규칙을 들수 있습니다.
자바 코드를 작성할 때 변수명은 카멜케이스를 지키는 것을 원칙으로 하지만 실제로 이 규칙을 어겨도 컴파일 오류가 발생하지는 않습니다. 이 클립스와 같은 개발 툴에서 이 규칙을 잘 지키고 있는지 별도의 알림을 주지 않으며 이것을 확인하는 작업은 지루하고 어려운 일이다. 그래서 체크스타일을 활용하면 도움
혼자만의 프로젝트든, 함께하는 프로젝트든, 기본적인 코드컨벤션이 있다면 코드의 가독성은 확 높아집니다. 그런데 이런 코드 컨벤션을 세워도, 매번 기억하거나 유의하기 어려울 때도 있죠. PR 에 코드 컨벤션에 대한 코멘트만 적힌다면, 마음이 상하기도 쉽습니다.
이런 부분은 코드의 정적분석으로 해결할 수 있는데요. sonarqube 같은 정적 분석기를 github에 붙일 수도 있겠지만, 일단 개개인의 ide에서 코드 컨벤션을 잡아주고 수정해줄 수 있는 방법이 필요합니다.
먼저 code style 과 checkstyle 은 다릅니다.
code style은 intelliJ 의 기본 기능으로, intelliJ 설정에서 앞으로 작성될 코드가 어떻게 작성될 지 기본적인 룰을 정합니다. 이 값은 앞으로 에디터에 작성될 코드에 적용됩니다.
code style은 intelliJ의 GUI 설정으로 수정할 수도 있지만, xml 파일로 관리할 수도 있습니다. 그리고 이 code style 을 정하면 이에 따라서 formatter 도 정해집니다. 따라서 code style을 정하면 formatter 도 정해진다! ![code style]](./3.png)
반면 checkstyle 은 별도의 플러그인으로서, checkstyle 에 따라서 코드 전체 혹은 일부를 원하는 때에 정적분석하면서 코드를 체크할 수 있는 플러그인입니다. 이 컨벤션은 code style과는 별도의 xml 로 관리됩니다.
롬복의 AccessLevel
@NoArgsConstructor(access = AccessLevel.PROTECTED)를 사용하면 객체 생성 시 안전성을 어느 정도 보장받을 수 있습니다.
AccesLevel은 생성자에 붙여주어 생성자 메소드를 private이냐 protected냐 public이냐인데 주로 public과 priate으로 나누어집니다. NoArgs를 사용하면 생성자 메소드를 따로안만들기떄문에 롬복을 이용해서 접근제어자를 설정하는게 좋습니다.
https://blog.live2skull.kr/java/lombok/java-lombok/
빌더패턴과 final키워드
빌더패턴을 사용하면 Setter를 안만들고 값을 넣을 수 있으며 유연하게 생성할 수 있기때문에
변경가능성을 최소화 시킬수 있습니다.
제가 final키워드랑 연관시킨이유는 불변성이 개발하면서 매우중요하다고생각합니다.
특히 회원가입로직에서의 dto에서의 불변이 중요합니다. 그래서 final키워드를 SignUpDto의 필드에 추가하고 @RequiredArgsConstructor를 달려고했지만 테스트코드에서의 ObjectMapper로 직렬화 역직렬화 문제가 생겼으며 그리고 중복적인 빌더패턴사용과 중복적인걸로 생각했습니다. 그렇지만 아래 코드와 같이 매개변수에 사용한다면 불변성을 확보해주는 기능을 얻을수있겠구나 하고 리펙토링과정을 가졌습니다
raw type -> 명시적 type
개발을 진행하면서
Raw 타입을 사용하면 컴파일 시점에 문제를 잡지 못하다가 런타임 시점에 ClassCastException 에러가 발생할 수 있다. 예를 들어 다음과 같은 Integer만을 갖는 List에 String이 추가되어도 오류 없이 컴파일되고 실행된다.
그러다가 해당 데이터를 꺼내거나 연산을 할 때 즉, 런타임 시점에 문제(ClassCastException 에러)가 발생하게 된다.
하지만 만약 Raw 타입이 아니라 타입 파라미터를 List<Integer>로 명시해준다면, 컴파일러가 리스트에 Integer만 넣어야 함을 인지하여 컴파일 시점에 오류를 잡아낼 수 있다. 왜냐하면 컴파일러는 컬렉션에서 원소를 꺼내는 모든 곳에 보이지 않는 형변환을 추가하여 절대 실패하지 않음을 보장하기 때문이다.
그래서 컴파일 시점에 에러를 잡는것이 매우 좋기떄문에 명시적 으로 타입을 선언해주게 많은 장점이 있습니다.
리펙토링과정에서 이러한 부분들만 살펴봐도 더 좋은 코드가 개발될것입니다. 저도 이러한 부분을 리펙토링과정에서 응용하게되었습니다.
참고 :
https://mangkyu.tistory.com/137?category=761302
'Delivery' 카테고리의 다른 글
Mybatis batch처리 성능과 트랜잭션 (0) | 2022.08.01 |
---|---|
테스트코드의 MockMvc utf-8 성능측정 (0) | 2022.07.19 |
Mybatis ${}, #{} 차이 (0) | 2022.07.17 |
피드백 반영 리펙토링 후기 (0) | 2022.07.16 |
Home-Delivery 개념 모델링 (0) | 2022.06.28 |