본문 바로가기
소프트웨어

코드 리팩토링 (Code refactoring)

by 꿈 너머 세계 2023. 2. 12.

리팩토링

코드 리팩토링은 기존 코드의 동작을 바꾸지 않고 코드를 재조합, 재구성하는 과정이다. 리팩토링의 목표는 코드를 더 이해하기 쉽게 만들고, 유지보수 및 확장을 더 쉽게 함으로써 코드의 품질을 향상시키는 것이다. 

코드를 리팩토링하는 일반적인 이유는 다음과 같다.

코드 가독성 향상:

 코드는 혼자 관리하지 않고 팀이 함께 관리하는 경우가 대부분이다. 그래서 코드 가독성의 중요성은 정말 중요하다. 리팩토링은 코드의 복잡성을 줄이고 의도를 명확히 한다. 코드의 전반적인 구조를 개선함으로써 코드를 더 쉽게 이해할 수 있도록 만들어서 생산성을 향상 시킨다.

새 기능을 개발하기 전 준비:

 기존의 코드가 구조가 안좋거나 비효율적이라면 새로운 기능을 추가하기가 쉽지 않다.

그래서 새로운 코드를 구현하기 전에 문제가 되는 부분을 개선하고 향상 시키는 것을 말한다.

리팩토링은 기존 코드의 구조를 개선하여 새로운 기능을 더 쉽게 추가할 수 있게 하여 모듈화 및 유연성을 높일 수 있도록 한다.


성능 향상:

 코드 가독성 및 구조 변경 뿐만아니라 성능적인 부분을 개선하는 것도 리팩토링의 목적이라 볼 수 있다. 리팩토링은 불필요한 논리식을 줄이거나, 데이터 구조를 최적화하거나, 메모리 사용을 개선함으로써 성능을 향상 시킨다.


Code smell 수정: Code Smell(나쁜 코드를 칭함)는 긴 메서드, 중복된 코드 또는 복잡한 제어 구조와 같이 문제를 포함할 수 있음을 나타내는 코드의 특정 특성을 말합니다. 리팩토링은 코드 냄새를 제거하고 코드의 품질을 향상시키는 데 도움이 될 수 있다.


코드 리팩토링 기술은 변수와 함수의 이름 변경, 별도의 함수로 코드 추출, 코드 중복 제거, 데이터 구조의 사용 개선 등 다양하다. 작은 단계로 쪼개서 리팩터링을 수행하고 각 변경 후 코드의 동작이 변경되지 않았는지 확인하는 것이 중요하다.

리팩터링은 시간이 많이 걸리는 프로세스일 수 있지만, 코드양이 증가함에 따라 관리할 수 있고 확장 가능한 상태를 유지하기 위해 필요하다. 코드를 리팩터링하는 데 시간을 많이 할애하면 소프트웨어의 장기적인 상태를 개선하여 향후 더 쉽게 코드를 관리할 수 있게 된다. 당장은 기능적인 부분이 추가되는게 아니라서 불필요한 부분이라 생각할 수 있겠지만 장기적인 관점에서 보면 코드 리팩토링은 생산성을 향상시키므로 코드 관리에 크게 도움이 된다.

 

코드 냄새 (Code smell)

리팩토링을 하기 위해서는 어떤 코드가 안좋은 코드인지 먼저 확인할 필요가 있다.

 

Code smell은 코드의 안좋은 특성을 설명하기 위해 사용되는 용어로, 코드에 문제가 있을 수 있음을 나타낸다. 코드 스멜이 반드시 버그인 것은 아니지만, 개선으로 이득을 볼 수 있는 코드의 영역을 나타낼 수 있다. 일반적인 코드 스멜은 다음과 같다.

 

복잡한 제어 구조: 이 코드 스멜은 중첩된 if 문 또는 중첩된 들여쓰기와 같은 복잡하고 이해하기 어려운 제어 구조를 나타낸다.


중복된 코드: 이 코드 스멜은 여러 곳에서 동일한 코드가 반복되는 경우를 의미한다. 코드가 중복되면 코드를 유지 관리하기가 더 어려워지고 한 곳에서 변경이 이루어지지만 다른 곳에서는 변경되지 않을 경우 불일치가 발생할 수 있다.

3 strike 룰을 소개한다. 코드를 구현하다가 3번째 중복 코드가 발생하게 될 경우 함수로 추출해서 중복코드를 제거하도록 하자.

 

거대한 클래스: 이 코드 냄새는 메서드와 변수가 너무 많아 목적과 행동을 이해하기 어려운 클래스를 말한다. 클래스 목적에 맞게 한 가지 일을 하도록 하자.


긴 함수: 이 코드 스멜은 지나치게 길고 이해하기 어려운 함수를 말한다. 함수가 길면 코드의 의도와 동작을 이해하기가 어렵다.

사용되지 않는 코드: 이 코드 스멜은 더 이상 사용되지 않지만 코드베이스에서 제거되지 않은 코드를 나타낸다. 사용되지 않는 코드는 코드 베이스를 이해하고 유지하기 어렵게 만든다. 미래에 사용한다고 생각하고 삭제 하지 않지만 코드를 더럽게할 뿐이다.

스위치 문: 이 코드 스멜은 과도하게 길거나 많은 분기를 포함하는 스위치 문을 말하며 코드를 더 이해하기 어렵게 만든다.

이럴 경우 Map 구조를 이용하여 개선할 수 있다.

하드 코딩된 값: 이 코드 스멜은 값이 상수 또는 변수로 정의되는 대신 코드에 하드 코딩되는 인스턴스를 나타낸다. 하드 코딩된 값은 코드를 유지하고 이해하기 어렵게 만든다. 하드 코딩된 값이 있다면 상수 또는 변수를 정의하여 사용하도록 하자.

코드 스멜을 학습하고 해결방법을 숙지하면 코드의 품질을 향상시키고 유지 관리를 쉽게 할 수 있다. 그러나 코드 냄새가 있다고 해서 반드시 코드가 잘못되었다고는 할 수 없다. 올바르게 수행되지 않을 경우 코드에 버그가 발생할 수 있으므로 리팩터링에 주의하여 접근해야 한다. 그래서 리팩토링을 하게 된다면 반드시 Test case를 보충하여 수정 전, 후에 차이가 없는지 확인하도록 하자.

 

리팩터링 유형

 

리팩터링은 다음과 같은 다양한 유형으로 수행할 수 있다.

 

클린 코드 리팩터링 (Clean code refactoring) : 이러한 유형의 리팩터링의 목적은 코드를 더 읽기 쉽고 유지보수 가능하게 만드는 것을 말한다. 클린 코드 리팩토링의 예로는 코드 중복 감소, 코드 주석 개선, 코드의 복잡성 감소 등 많은 기법들이 있다.

성능 리팩터링 (Performance refactoring) : 이러한 유형의 리팩터링은 코드의 성능을 향상시키는 것을 말한다. 성능 리팩토링의 예로는 데이터 구조 최적화, 계산 횟수 감소, 메모리 사용 개선 등이 있다.

구조 리팩터링 (Structural refactoring): 코드의 동작을 변경하지 않고 코드의 구조를 변경하는 것을 포 말한다. 구조 리팩토링의 예로는 코드를 별도의 함수로 이동, 변수 이름 변경, 데이터 구조 개선 등이 있다.

행동 리팩터링 (Behavioral refactoring): 코드의 구조를 유지하면서 코드의 동작을 변경하는 것을 포함한다. 행동 리팩토링의 예로는 버그 수정, 성능 향상, 새로운 기능 추가 등이 있다.

기술 부채 리팩터링 (Technical debt refactoring) : 기술 부채 또는 시간이 지남에 따라 코드를 유지하고 개선하는 누적 비용을 지불하는 것을 말한다. 기술 부채 리팩토링의 예로는 버그 수정, 성능 향상, 코드 확장성 향상 등이 있다.

위 예제는 다양한 유형의 리팩터링의 몇 가지 예에 불과하다. 사용하기에 가장 좋은 리팩터링 유형은 코드의 특정 요구와 상황에 따라 달라진다. 리팩토링을 수행하면 코드베이스의 품질을 향상시키고 향후 코드베이스를 더 쉽게 이해, 유지 및 확장할 수 있다. 그러므로 다양한 리팩토링 기법을 숙지하고 상황에 맞게 사용하면 효율적인 코드를 유지하고 관리하는데 많은 도움이 될 것이다.

댓글