본문 바로가기

TIL

TIL - 코드 리팩토링(Code refactoring)을 하는 이유

정의


코드 리팩토링(Code refactoring)은 외부 동작을 변경하지 않고 기존 컴퓨터 코드를 재구성(팩터링 변경)하는 프로세스를 말합니다.

 

요약

  • 소프트웨어의 기능을 유지하면서 소프트웨어의 설계, 구조 및/또는 구현(비기능적 속성)을 개선하기 위한 것입니다.
  • 리팩터링의 잠재적 이점으로는 코드 가독성 향상과 복잡성 감소를 들 수 있는데, 이는 소스 코드의 유지보수성을 개선하고 더 간단하고 깔끔하며 표현력이 풍부한 내부 아키텍처 또는 객체 모델을 만들어 확장성을 향상할 수 있습니다.
  • 코드 리팩터링을 잘 수행하면 소프트웨어 개발자가 기본 로직을 단순화하고 불필요한 복잡성을 제거하여 시스템의 숨겨진 버그나 휴면 상태의 취약점을 발견하고 수정하는 데 도움이 될 수 있습니다.
  • 리팩토링을 잘못 수행하면 외부 기능을 변경하지 않아야 한다는 요건을 충족하지 못하여 새로운 버그가 발생할 수 있습니다.

 

 

코드 리팩토링(Code refactoring)을 하게 되는 이유

 

리팩터링은 일반적으로 코드 냄새[각주:1]를 발견함으로써 동기가 부여됩니다.

예를 들어, 현재 사용 중인 메서드가 매우 길거나 근처에 있는 다른 메서드와 거의 중복되는 경우

 이러한 문제를 인식하면 소스 코드를 리팩터링 하거나 이전과 동일하게 작동하지만 더 이상 '냄새'가 나지 않는 새로운 형태로 변환하여 문제를 해결할 수 있습니다.

 

 

리팩토링 장점

 

유지보수성

  • 소스 코드가 읽기 쉽고 작성자의 의도를 파악하기 쉽기 때문에 버그를 수정하기가 더 쉽습니다. 이는 대규모 모놀리식 루틴을 개별적으로 간결하고 이름이 잘 지정된 단일 목적의 메서드 집합으로 줄임으로써 달성할 수 있습니다.
  • 메서드를 더 적절한 클래스로 옮기거나 오해의 소지가 있는 주석을 제거함으로써 이를 달성할 수 있습니다.

확장성

  • 인식 가능한 디자인 패턴을 사용하면 애플리케이션의 기능을 더 쉽게 확장할 수 있으며, 이전에는 없던 코드의 유연성을 제공합니다

 

리팩토링을 하는 시기

 

리팩터링은 두 가지 시기가 있습니다

  1. 예방적 리팩토링: 코드를 작성할 때 냄새가 없을 때 코드를 더욱 견고하게 만들어 향후 냄새가 발생하지 않도록 합니다.
  2. 수정 리팩터링: 나중에 개발자가 코드 냄새가 발생했을 때 올바른 코드 냄새를 위해 리팩터링을 수행합니다

 

리팩토링의 적용방법

단위 테스트가 준비되면 리팩터링은 작은 프로그램 변형을 만들고, 이를 테스트하여 정확성을 확인하고, 또 다른 작은 변형을 만드는 반복적인 주기로 이루어집니다. 어느 시점에서든 테스트가 실패하면 마지막 작은 변경을 취소하고 다른 방식으로 반복합니다. 수많은 작은 단계를 통해 프로그램은 원래 있던 위치에서 원하는 위치로 이동합니다. 이 반복적인 프로세스가 실용적이려면 테스트가 매우 빠르게 실행되어야 하며, 그렇지 않으면 프로그래머는 테스트가 완료될 때까지 기다리는 데 많은 시간을 소비해야 합니다. 익스트림 프로그래밍 및 기타 애자일 소프트웨어 개발을 지지하는 사람들은 이 활동을 소프트웨어 개발 주기의 필수적인 부분이라고 설명합니다.

 

 

 

리팩토링 예시

// 리팩토링전 화면에 영화 카드 생성 함수
function displayMovies(movies) {
    const movieList = document.getElementById("movie-list");
    movieList.innerHTML = ""; // Clear existing movie cards
    movies.forEach((movie, index) => {
        const movieCard = document.createElement("div");
        movieCard.classList.add("movie-card");
        movieCard.id = `${movie.id}`;

        const img = document.createElement("img");
        img.src = `https://image.tmdb.org/t/p/w500${movie.poster_path}`;
        img.alt = movie.title;

        const title = document.createElement("h3");
        title.classList.add("movie-title");
        title.textContent = movie.title;

        const content = document.createElement("p")
        content.classList.add("movie-content");
        content.textContent = movie.overview;

        const rating = document.createElement('div');
        rating.classList.add('movie-rating');
        rating.textContent = `⭐ ${movie.vote_average.toFixed(1)}`

        movieCard.append(img, title, rating, content);
        movieList.appendChild(movieCard);
    })
}
// 영화 타이틀 요소 생성 함수
const createMovieTitle = (titleText) => {
    const title = document.createElement("h3");
    title.classList.add("movie-title");
    title.textContent = titleText;
    return title;
};

// 영화 소개 요소 생성 함수
const createMovieContent = (overviewText) => {
    const content = document.createElement("p");
    content.classList.add("movie-content");
    content.textContent = overviewText;
    return content;
};

// 영화 평점 요소 생성 함수
const createMovieRating = (voteAverage) => {
    const rating = document.createElement('div');
    rating.classList.add('movie-rating');
    rating.textContent = `⭐ ${voteAverage.toFixed(1)}`;
    return rating;
};

// 영화 카드 생성 함수
const createMovieCard = (movie, index) => {
    const movieCard = document.createElement("div");
    movieCard.classList.add("movie-card");
    movieCard.id = `${movie.id}`;

    const img = document.createElement("img");
    img.src = `https://image.tmdb.org/t/p/w500${movie.poster_path}`;
    img.alt = movie.title;

    const title = createMovieTitle(movie.title); // 영화 타이틀 요소 생성
    const content = createMovieContent(movie.overview); // 영화 소개 요소 생성
    const rating = createMovieRating(movie.vote_average); // 영화 평점 요소 생성

    movieCard.append(img, title, rating, content);
    return movieCard;
};

 

위 코드의 올바른 함수명과 각 요소(영화 타이틀, 소개, 평점)를 생성하는 함수를 만들어 재사용할 수 있도록 리팩토링 했습니다. 이렇게 하면 코드의 가독성이 향상되고, 유지보수가 쉬워집니다. 또한, 코드의 재사용성이 높아지고 중복이 줄어들어 코드의 효율성이 증가합니다.

 

리팩토링 하면서 주의할 점은 리팩토링 과정에서 함수명을 바꾸는데 페이지를 새로고침 하는 기능인 함수의 명을 명확히 하려고 reloadPage()로 바꾼 결과

함수 이름 충돌

기존에 "표준 개발 도구를 사용하여 iframe 기반 웹 보기"의 reloadPage() 함수가 있어서 이름 충돌같이 생각하지 못한 오류가 발생할 수 있어서 주의하면서 리팩토링 해야 합니다.

  1. 코드 냄새는 프로그램의 소스 코드에서 더 심각한 문제를 나타낼 수 있는 모든 특성을 말합니다. 무엇이 코드 냄새인지 아닌지를 판단하는 것은 주관적이며 언어, 개발자 및 개발 방법론에 따라 다릅니다. [본문으로]