리팩토링(Refactoring)

  • 결과의 변경 없이 코드의 구조를 재조정함
  • 가독성을 높이고 유지보수를 편하게 함
  • 버그를 없애거나 새로운 기능을 추가하는 행위는 아님

코드 스멜(Code Smell)

  • 개발자가 이해하거나 유지보수하기 어려워 리팩토링 대상이 되는 코드
  1. Duplicated Code(중복코드) : 중복된 코드
  2. Long Method(긴 메소드) : 긴 메소드 내용
  3. Long Class(방대한 클래스) : 한 클래스에 많은 속성과 메소드 존재
  4. 과대한 매개변수 : 메소드의 파라미터 개수가 많음
  5. Divergent Change(수정의 산발) : 하나의 클래스에 발생하는 잦은 변경
  6. Shotgun Surgery(기능의 산재) : 변경 발생 시 많은 클래스의 수정
  7. Feature Envy(잘못된 소속) : 객체 안의 메소드의 데이터가 잘못 연결
  8. Data Clump(데이터 뭉치) : 동일한 목적/사용용도인 3~4개의 몰려있는 데이터
  9. Temporary Field(임시필드) : 클래스 안의 인스턴스 변수가 특정 상황에서만 사용되는 것. 대부분은 실제 사용되지 않는 변수
  10. Switch Statements(Switch문) : switch문은 중복 코드의 발생 확률이 높음
  11. Comments(불필요한 주석) : 코드 스멜을 감추기 위한 많은 주석

즉, 리팩토링은 코드 스멜을 제거하기 위해서 진행하는 것이다.

리팩토링 기법 종류

리팩토링 기법

코드 스멜리팩토링 기법설명
Duplicated CodeExtract Method
Extract Class
Extract Interface
중복된 코드를 별도의 메소드, 클래스, 인터페이스로 추출하여 재사용이 가능하게 만드는 것
Long MethodExtract Method
Split Temporary Variable
Introduce Explaining Variable
긴 메소드를 여러 개의 작은 메소드로 분리하여 가독성을 높이고, 이해하기 쉽도록 하는 것
Long ClassExtract Class
Extract Subclass
Extract Interface
방대한 클래스를 여러 개의 클래스로 나누어 각 클래스가 단일 책임을 가지도록 하는 것
Overlong Parameter ListIntroduce Parameter Object
Extract Method
많은 파라미터를 가진 메소드를 하나의 객체로 묶거나, 메소드를 분리하여 파라미터 개수를 줄이는 것
Divergent ChangeExtract Class
Extract Interface
Separate Interface
클래스가 여러 가지 변경에 영향을 받는 경우 클래스를 분리하거나 인터페이스를 통해 책임을 나누는 것
Shotgun SurgeryExtract Method
Extract Class
Move Method
Move Field
하나의 변경이 여러 클래스를 수정해야 하는 경우, 메소드와 필드를 적절한 클래스로 이동시켜 책임을 분리하는 것
Feature EnvyMove Method
Move Field
Extract Class
메소드가 자신이 속하지 않은 클래스의 데이터에 과도하게 의존하는 경우, 메소드와 필드를 적절한 클래스으로 이동시키는 것
Data ClumpExtract Class
Introduce Parameter Object
관련된 데이터를 하나의 객체로 묶거나 클래스로 추출하여 데이터의 응집도를 높이는 것
Temporary FieldExtract Method
Remove Assignment to Parameters
Extract Class
특정 상황에서만 사용되는 임시 변수를 적절한 메소드나 클래스로 추출하여 변수의 범위를 줄이는 것
Switch StatementsReplace Conditional with Polymorphism
Extract Method
Use Enum
스위치 문을 다형성, 메소드 추출, 또는 열거형을 사용하여 대체하여 중복 코드를 줄이고 확장성을 높이는 것
CommentsRemove Comment
Refactor Code
코드가 스스로 설명하도록 리팩토링하여 불필요한 주석을 제거하는 것

AttendancePostsService

Autowired 제거

Autowired 어노테이션을 제거한 후 생성자 주입을 사용하여 의존성 주입

@RequiredArgsConstructor
public class AttendancePostsService {
    //생성자 말고 setter 메소드를 만들어서 자동 호출
    //Autowired, setter 메소드, 생성자 중 골라야 함 -> setter가 보안상 좋음
    private final AttendancePostsRepository attendancePostsRepository;
    private final UserRepository userRepository;
    private final OpenAIService openAIService;
}

Switch문 제거 + String 변수 선언

private int determineAttendanceType(String attendanceType) {
        int answer = 0;
        switch (attendanceType) {
            case "'과소비'":
                answer = 1;
                break;
            case "'절약'":
                answer = 2;
                break;
            case "'판단안됨'":
                answer = 3;
                break;
        }
        return answer;
    }

기존의 switch문을 Map으로 구현하였다. 그와 동시에 각 타입에 대한 final 변수를 선언해 주었다(추후 이름 변경에 대비)

private static final Map<String, Integer> attendanceTypeMap = new HashMap<>();
 private static final String TYPE_OVRSPENDING = "'과소비'";
    private static final String TYPE_SAVING = "'절약'";
    private static final String TYPE_UNDETERMINED = "'판단안됨'";

    static {
        attendanceTypeMap.put(TYPE_OVRSPENDING, 1);
        attendanceTypeMap.put(TYPE_SAVING, 2);
        attendanceTypeMap.put(TYPE_UNDETERMINED, 3);
    }
    
    
     private int determineAttendanceType(String attendanceType) {
        return attendanceTypeMap.getOrDefault(attendanceType, 0);
    }

삼항연산자 사용

 public String switchPostTypeFromNumToWord(int typeNum){
        if(typeNum == 1){
            return "overspending";
        }
        return "saving";
    }

if문을 삼항연산자를 사용하여 간결하게 변경

 public String switchPostTypeFromNumToWord(int typeNum) {
        return typeNum == 1 ? "overspending" : "saving";
    }

return type 간소화

 String[] responses = new String[2];
        responses[0] = responseType;
        responses[1] = responseContent;
        return responses;

기존에는 배열을 만들어서 그 배열에 각각을 담고 return을 해 주었다면, 한번에 배열에 요소를 담아서 return하도록 수정

        return new String[]{responseType, responseContent};
profile
컴퓨터가 이해하는 코드는 바보도 작성할 수 있다. 사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다. -마틴 파울러

0개의 댓글