[리팩토링] 계획

이정환·2023년 8월 7일
0

[개인 프로젝트]

목록 보기
3/8

기능구현 -> 리팩토링

meetup 프로젝트는 기능 구현에 중점을 두고 개발했다. 기능 작동되니 다음 단계는 코드의 가독성, 중복제거, shell script, 테스트 등 수정 계획이다.

한 주동안 어떻게 하면 리팩토링 할 수 있는 안목을 기를 수 있을까 찾아다녔다. 유튜브 둘러보고, 도서관에서 책들 훑고, 스프링 오픈소스 열어보기, 다른 동료의 코드리뷰 등 이것저것했다. 정말 좋은 컨텐츠가 많았지만 지금 이순간 가장 실용적이었던 것은 다른 프로젝트의 코드를 보고 그 패턴을 익히는 것이었다.

깃허브에서 java spring 으로 만들어진 백엔드 프로젝트를 찾아봤다. 보면서 내 코드와 비교하니 어디를 개선하면 좋을지 아이디어 떠올랐다. 참 많다... 이것말고도 고치고 고치고 고쳐야될 텐데 약간 기대된다.

리팩토링 계획

  1. DB 정규화
    • 업로드 파일과 이미지 파일을 엔티티별로 따로 관리하고 있다. 코드도 각 엔티티별로 만들어서 3개씩 존재한다.중복있다. 엔티티와 코드를 1개로 합칠까 생각했다. 코드는 확실히 엄청 유사하니 한 모듈 내 콩통 로직으로 묶을 수 있다고 판단된다. 하지만 엔티티는 데이터의 일관성을 유지하기 위해서 그대로 두는게 낫겠다는 판단 든다.
    • 코드 수정하다가 필요성 발견되면 DB 정규화 할 것이지만, 아직은 필요성 보이지 않는다.
  2. 업데이트
    • 부분 수정은 patch 메소드로 고치고, 전체 덮어쓰기는 put 쓰고, 영속성컨텍스트 더티체킹 기능 활용으로 내부에서 데이터 호출 후 수정하는 코드로 간단하게 업데이트 쪽은 수정해야겠다.
  1. 설정
    • application.yml dev, prod, local 별 관리하는 환경셋팅
      -실행환경별 로그 출력 aop
    • ddl 대신 sql init + shell
      -어드민 유저 생성
    • 테스트 환경은 h2 db 사용
    • properties묶음 관리 - (mail, oauth, jwt, db, ...)
    • properties와 config는 분리해서 관리
  1. 코드 수정 및 추가 기능
  • 생성자 사용시 static of 사용. pagenate 내장 클래스도 이 방법을 사용하고, 이를 사용하게 되면 생성자 생성시 내부에서 예외 체크 할 수 있다. 또한 특정 인스턴스와 관련없음을 명시해서 해당 메소드로 인한 상태 변화는 클래스만 된다는 것을 명시할 수 있어서 가독성 향상 될 것이라 생각한다.

  • try-catch를 줄임. 테스트 코드를 줄일 수 있고 가독성 향상 시킬 수 있고 기능 최적화 가능하다.

  • custom annotation은 기능

  • social login을 spring security 없이 구현 계획

  • cookie manager 쿠키의 생성 및 파싱 등 관리하는 모듈을 만드는 게 가독성 및 유지관리 효율

  • stream().collect(), collectors, hashmap<> 등 collector 프레임워크를 최대한 적용. 기능 향상 및 코드 가독성

    • "dto::getter" 이런 형식 사용. 매개변수 추론인듯?
  • @query fetch join

  • @Lock

    • 낙관적락 비관적락
  • @Transactional(readOnly = true)

  • mapper (obj -> dto, dto->obj, dto 생성), 이전 코드는 각 엔티티 및 각 dto에서 맵핑 기능을 구현했지만 mapper라는 하나의 클래스에서 관리하게 하면 코드 가독성 및 유지보수 효율
    -@mapper() - A -> Adto 없는 필드 기본값 셋팅가능(dto에서 @allargsconstrutor 때문인듯)
    - 셋팅안하면 못 씀
    - 참조값은 기본값 자동설정 어렵다네
    - 여러 참조값넣는데 겹치는 값 있을때 사용

    • 일일히 객체 -> 객체dto 값할당 방식 제거
    • 만들려는 DTO에 해당하는 필드에 알아서 일치되는것만 넣어줌
    • @mapping이나 인자로 넣나 동작은 같은데, 로직이 복잡해서 명시적 표현
  • javadoc
  • 페이징 수정

  • service로직에서 R과 CUD를 분리. R은 인덱스 및 최적화 코드로 직접 관리할 수 있도록 구분해서 두고, 트랜잭션이 필요한 서비스만 따로 묶고, 트랜잭션 필요하지 않은 서비스 따로 묶어서 최소 3개의 덩어리로 구분하기

  • admin은 주로 유저 요청이 제대로 동작되지 않거나, 제제를 가한다는 전제에서 기능 추가

  • dto는 엔티티 존재 시 들어온 요청에 대한 데이터 , 응답할 데이터 최대 2개로 만들어서 domain/dto에서 관리. 엔티티 없으면 공통 dto폴더 내 개별관리.

  • 생성자 빌더패턴 사용. 유연한 매개변수를 가진 생성자를 만들 수 있음.
    -롬복의 빌더패턴 (cf. 기본생성자+셋터주입 , 생성자주입과 같이 객체만들기 위함이지만, 할당하는 객체 값이 어디에 되는지 가독성 향상 및 순서 어겨도됌), 빌더채턴은 내부적으로 기본생성자 생성+셋터주입
    -@NoArgsConstructor(access = AccessLevel.PROTECTED) 사용해도 빌더패턴사용가능함. 두개를 같이 쓰는게 캡슐화에 안전
    -@Builder(allArgsConstructor = true) 빌더에 강조할수있음.
    -@Builder() - 매개변수 갯수가다른 객체 코드 작성할 필요 없이 사용가능.
    -@builder() 만 사용한다면, 이는 기본생성자, 모든 값을 할당하는 생성자, 일부 값만 할당하는 생성자 를 만들수있단느 것을 의미하니까 @AllArgsConstructor와 @NoArgsConstructor(access = AccessLevel.PROTECTED) 를 쓰지 않는게 낫
    -이거 위 설명 틀릴수도 잇어직접테스트 해봐야됌.

  • domain에 equals, hashcode 오버라이딩 하고, isvalid 메소드 구현 및 셋터 내 사용.

  • @EqualsAndHashCode(onlyExplicitlyIncluded = true) @EqualsAndHashCode.Include

  • @embeddable ( 다른 엔티티에서 재사용할 수 있는 값 타입을 정의할 때 사용)

  • swagger 이나 javadoc 관리 모듈로 구분하면 좋을듯

  • {} 형식 데이터 관리를 적극적으로 할 필요.
    @JsonUnwrapped -> 멤버변수로 어떤 객체를 사용하는데, 이걸 JSON변환할때, 가령 api응답할때 가만히두면 한단계 깊이에서 객체만들어지는데 그걸 부모수준으로 끌어올려서 한단계 더 깊이 안들어가도 되게 함

  • @EventListener 특정 동작발생시 마치 트리거처럼 작동되는 기능인듯. 비동기처리, 로그, 알림 등 여러기능으로사용

  • 예외에 대한 메시지를 한 Enum에서 전부 관리하게 해서 코드 가독성 높이기

  • 룸이나 유저 검색시 특정 글자 포함시 검색하도록

  • 통계 관련 모듈

  • 일반유저를 어드민 만드는 로직 추가

  • cookiemanager 처럼 datemanager(jwt, room) 구현

  • enum은 전부 enum폴더에서 관리하게 하고, 차라리 dto도 그렇게 해보는걸 고민

  • nginx, 캐싱

  • 환경변수를 중복되지 않게 따로 한번에 관리 (code, test, docker, git action)

  1. 테스트 코드
  • db init sql 환경
  • 테스트 자체 도커
  • 모듈, 컨트롤러, 도메인, 서비스 별 테스트
  • mokito 단위테스트 , 스프링 통합테스트 부분 의도적 분리.

1개의 댓글

comment-user-thumbnail
2023년 8월 7일

유익한 글이었습니다.

답글 달기