어플리케이션 리팩토링 (Application Refactoring) – 1

computer-coding

어플리케이션 리팩토링(Application Refactoring)이란?

프로그램을 겉으로 보이는 동작의 변화 없이 내부 구조를 변경하는 작업입니다.

예를 들어 버그 수정이나 기능 추가는 리팩토링이라 할 수 없는데 그 이유는 외부동작의 변화가 있기 때문입니다. 반면에 소스정리를 리팩토링이라고 흔히 생각하는 경우가 많은데 이 경우도 코드의 가독성을 높이는 것이지 내부 소스의 구조를 변경하는 것은 아닙니다.

리팩토링을 하게 되면 코드를 쉽게 이해하고 수정할 수 있게 하므로 유지보수를 하기 용이하며  세밀한 코드 분석을 통하여 잠재적인 오류까지 같이 발견하여 조치 할 수 있는 효과가 있습니다.

리팩토링을 해야할 상황으로는 코드가 이해하기 어렵거나 수정 또는 확장하기 어려울때로 구체적으로는 중복기능이 많거나 소스코드가 길때 메소드화 리팩토링이 필요하며 클래스의 크기가 너무 클 경우 클래스를 세분화 한다거나 클래스 혹은 메소드 명과 내부 동작 의미가 안맞을때 네이밍 변경, 구조가 객체 지향적이지 않을때 디자인 패턴 및 추상 클래스화하는 등의 리팩토링을 예로 들 수 있습니다.

반대로 리팩토링을 하지 말아야 할 때도 존재합니다. 프로그램이 아직 완전히 구현되지 않을 때와 시간이 너무 촉박하여 제품을 런칭하거나 납품할 때 입니다. 전자는, 프로그램 개발 도중에 리팩토링을 할 필요 없을 정도로 완전 무결한 코드로 구현 했을 경우는 해당 되지 않지만 그런 경우는 거의 없다고 봐야 될 것 입니다. 개발 하면서 리팩토링을 하게된다면 개발 일정이 늘어날 수 밖에 없기 때문에 프로그램을 일차적으로 완성시킨 후에 리팩토링 리뷰를 하는 것이 이상적입니다. 후자는 안정성에 대한 문제로 내조만간 프로그램을 배포하여야 하는데 중간에 리팩토링이 완전히 끝나지 않은 상태라면 리팩토링 이전보다 프로그램이 오류를 발생할 확률이 높을 수 있습니다.

이와 유사하게 리팩토링을 적용하기 어려운 영역도 있습니다. 데이터베이스는 어플리케이션에 지대한 영향을 미치므로 리펙토링보다 튜닝을 해야하며, Spring에서 Spring Boot 기반으로 변경같은 프레임워크가 변경하는 경우도 마찬가지로 코드 구조는 프레임워크에 종속되는 경우가 많으므로 적용하기가 어렵습니다.

이를 바탕으로 정답이 있는 코딩은 없지만 효율적이고, 유연하며, 쉽게 이해할 수 있는 코딩 수준은 리팩토링으로 향상시킬 수 있습니다.



리팩토링전의 체크사항

외부동작이 변경되지 않는다는 것을 확인하려면 단위 테스트가 필요합니다.

1) 기존소스 -> 테스트 코드 = 정상
2) 리팩토링 소스 -> 테스트 코드 = 정상

위 1)번과 2)번 결과가 같은 정상 값이 나와야 하며 2)번이 결과가 나오지 않는다거나 다른 결과 값이 나온다거나 한 것은 리팩토링 실패라고 정의 할 수 있습니다.
자바 진영에서는 jUnit, 닷넷 진영에서는 xUnit를 단위 테스트 프로그램으로 많이 쓰고 있습니다.

리랙토링 기법

구분 기법 설명
메소드 정리 Extract Method 그룹을 묶을 수 있는 코드를 별도 메소드로 추출
Replace Temp with Query 수식을 메소드로 변경, 메소드 호출로 단순화
객체간 기능이동 Move Method 다른 클래스의 기능이 더 많은 메소드를 대체
Extract Class 하나의 클래스에서 두개 클래스 업무 수행 시 분리
메소드 호출 단순화 Rename Method 메소드의 목적이 불분명한 경우 이름 변경
Remove Parameter 불 필용한 파라미터를 제거
클래스/메소드 일반화 Pull Up Field 두 서브 클래스가 동일한 필드를 가질경우 슈퍼클래스 이전
Pull Up Method 동일한 역할의 메소드가 여러 서브클래스에 분산 시 슈퍼클래스로 이전
기타 Encapsulation Field Public 필드를 Private으로 변경하고 접근자 생성
Decompose Conditional 조건 논리를 단순화하여 표현

메소드 정리

Extract Method : 그룹으로 묶을 수 있는 코드를 별도 메소드로 추출한다.

Extract Method

Replace Temp with Query : 수식을 메소드로 변경하고, 메소드 호출로 단순화한다.

Replace Temp with Query

객체간 기능이동

Move Method : 다른 클래스의 기능이 더 많은 메소드를 대체한다.

Move Method2

Move Method

Extract Class : 두 개 클래스가 해야할일을 하나의 클래스가 한다.

Extract Class2

Extract Class

메소드 호출 단순화

Rename Method : 메소드의 목적이 불분명한 경우나 메소드 명이 너무축약되어 가독성이 떨어지는 경우 변경한다.

Rename Method2

Rename Method

Remove Parameter : 불필요한(사용하지않는) 파라미터를 제거한다.

Remove Parameter

클래스/메소드 일반화

Pull Up Field : 두 서브클래스가 동일한 필드를 가질 경우 슈퍼클래스로 이전한다.

Pull Up Field

Pull Up Method : 동일한 역할의 메소드가 여러 서브클래스에 분산 시 슈퍼클래스로 이전한다.

Pull Up Method

기타

Encapsulation Field : Public 필드를 Private으로 변경하고 접근자 생성한다.

Encapsulation Field

Decompose Conditional : 조건 논리를 단순화하여 표현한다.

Decompose Conditional

댓글 남기기