Extract Method
- 정의
- 지나치게 긴 메소드를 보거나, 또는 목적을 이해하기 위해서 주석이 필요한 코드를 보면 그 부분을 하나의 메소드로 뽑아낸다.
- 메소드가 잘게 쪼개져 있을 때 다른 메소드에서 사용될 확률이 높아진다.
- 고수준의 메소드를 볼 때 일련의 주석을 읽는 것 같은 느낌이 들도록 할 수 있다. 또한 메소드가 잘게 쪼개져 있을 때 오버라이드 하는 것도 훨씬 쉽다.
- 작은 메소드는 실제로 이름을 잘 지었을 때만 그 진가가 드러나므로, 이름을 지을 때 주의해야 한다.
- 메소드의 이름과 메소드 몸체의 의미적 차이다. 뽑아내는 것이 코드를 더욱 명확하게 하면, 새로 만든 메소드의 이름이 원래 코드의 길이보다 길어져도 뽑아낸다.
- 메소드를 새로 만들고, 의도를 잘 나태낼 수 있도록 이름을 정한다. 어떻게 하는지를 나타내는 방식으로 이름을 정하지 말고, 무엇을 하는지를 나타내게 이름을 정한다.
Inline Method
- 정의
메소드 몸체가 메소드의 이름 만큼이나 명확할 때는, 호출하는 곳에 메소드의 몸체를 넣고, 메소드를 삭제하라. - 동기
메소드의 몸체가 메소드의 이름 만큼이나 명확할 때가 있다. 또는 메소드의 몸체를 메소드의 이름 만큼 명확하게 리팩토링 할 수도 있다. - 너무 많은 인디렉션이 사용되어 모든 메소드가 단순히 다른 메소드에 위임을 하고 있어, 그 인디렉션 속에서 길을 읽을 염려가 있을 때 사용한다.
- 메소드가 잘못 나누어져 있을 때에도 사용할 수 있다. 이런 경우 나누어져 있는 메소드를 다시 합쳐 하나의 큰 메소드로 만든 다음, 메소드를 다시 추출한다.
- Replace Method with Method Object를 사용하기 전에 이 리팩토링을 사용하면 좋다는 것을 알아냈다.
- 주의사항
메소드가 다형성을 가지고 있지 않은지 확인한다. 서브클래스에서 오버라이드하고 있는 메소드에는 적용하지 않는다. 수퍼클래스에 없는 메소드를 서브클래스에서 오버라이드 할 수는 없다.
Inline Temp
- 정의
간단한 수식의 결과값을 가지는 임시변수가 있고, 그 임시변수가 다른 리팩토링을 하는데 방해가 된다면, 이 임시변수를 참조하는 부분을 모두 원래의 수식으로 바꾸라. - 동기
대부분의 경우 Inline Temp는 Replace Temp with Query의 한 부분으로 사용된다. - 주의사항
Replace Temp with Query
- 정의
어떤 수식의 결과값을 저장하기 위해서 임시변수를 사용하고 있다면, 수식을 뽑아내서 메소드로 만들고, 임시변수를 참조하는 곳을 찾아 모두 메소드 호출로 바꾼다. 새로 만든 메소드는 다른 메소드에서도 사용될 수 있다. - 동기
- 임시변수는 임시로 사용되고, 특정 부분에서만 의미를 가지므로 문제가 된다. 임시변수는 그것이 사용되는 메소드의 컨텍스트 안에서만 볼 수 있으므로, 임시변수가 사용되는 메소드는 보통 길이가 길어지는 경향이 있다.
- 임시변수를 질의 메소드로 바꿈으로써 클래스 내의 어떤 메소드도 임시변수에 사용될 정보를 얻을 수 있다. 또한 이것은 클래스의 코드가 더 깔끔해 지도록 한다.
- Replace Temp with Query 는 Extract Method를 적용하기 전의 필수 단계이다. 지역변수는 메소드의 추출을 어렵게 하기 때문에 가능한 많은 지역변수를 질의 메소드로 바꾸는 것이 좋다.
- 주의사항
- 임시변수에 값이 여러 변 대입되는 경우에는 Split Temporay Variable을 먼저 적용한다.
- 반복문 같은 경우 이 리팩토링을 할 경우 퍼포먼스에 대해서 걱정이 될 것이다. 하지만 걱정하지 마라. 코드가 잘 분해되어 있으면, 보통 리팩토링을 하지 않았을 때에는 보지 못했을 더 강력한 최적화 방법을 찾을 수 있다. 최악의 경우라도, 임시변수를 다시 집어넣는 것은 쉽다.
Introduce Explaining Variable
- 정의
복잡한 수식이 있는 경우에는, 수식의 결과나 또는 수식의 일부에 자신의 목적을 잘 설명하는 이름으로 된 임시변수를 사용하라. - 동기
- 수식은 매우 복잡해져 알아보기가 어려워질 수 있다. 이런 경우 임시변수가 수식을 좀더 다루기 쉽게 나누는데 도움이 될 수 있다.
- 특히 조건문에서 각각의 조건의 뜻을 잘 설명하는 이름의 변수로 만들어 사용할 때 유용하다. 다른 경우로는 긴 알고리즘에서 각 단계의 계산 결과를 잘 지어진 이름의 임시변수로 설명할 수 있다.
- 지역변수 때문에 Extract Method를 사용하기 어려운 경우에도 사용한다.
- 주의사항
Introduce Explaining Variable 보다는 Extract Method 를 사용하라. Extract Method 가 사용하기 어려울 때에만 Introduce Explaining Variable를 사용해라. 만약 Replace Method with Method Object를 사용하게 된다면 임시변수 또한 유용하다.
Split Temporary Variable
- 정의
루프 안에 있는 변수나 collecting temporay variable도 아닌 임시변수에 값을 여러 번 대입하는 경우에는, 각각의 대입에 대해서 따로따로 임시변수를 만들어라. - 동기
어떤 변수든 여러가지 용도로 사용되는 경우에는 각각의 용도에 대해 따로 변수를 사용하도록 바꾸어야 한다. 왜냐하면 하나의 임시변수를 두 가지 용도로 사용하면 코드를 보는 사람이 매우 혼란스러울 수 있다.
- 주의사항
Remove Assignments to Parameters
- 정의
파라미터에 값을 대입하는 코드가 있으면, 대신 임시변수를 사용하도록 하라. - 동기
- 값에 의한 전달에서는 파라미터에 어떤 변경을 가하더라도 호출하는 루틴 쪽에는 반영되지 않는다. 참조에 의한 전달을 사용하던 사람들에게는 아마도 이것이 헷갈릴 것이다.
- 메소드 몸체 안의 코드 자체에서도 혼동이 된다. 따라서 파라미터는 전달된 그대로 쓰는 것이 일관적인 사용법이고, 훨씬 명확하다.
- 지역변수 때문에 Extract Method를 사용하기 어려운 경우에도 사용한다.
- 주의사항
자바에서는 파라미터에 값을 대입해서는 안된다.
Replace Method with Method Object
- 정의
긴 메소드가 있는데, 지역변수 때문에 Extract Method를 적용할 수 없는 경우에는, 메소드를 그 자신을 위한 객체로 바꿔서 모든 지역변수가 그 객체의 필드가 되도록 한다. 이렇게 하면 메소드를 같은 객체 안의 여러 메소드로 분해할 수 있다. - 동기
지역변수는 메소드를 분해할 때 어려움을 준다. 즉 지역변수가 많으면 분해가 어려워질 수 있다. Replace Temp with Query는 이런 짐을 덜도록 도와주지만, 때로는 쪼개야 하는 메소드를 쪼갤 수 없는 경우가 생길 수도 있다. 이런 경우에 사용한다.
Substitute Algorithm
- 정의
알고리즘을 보다 명확한 것으로 바꾸고 싶을 때는, 메소드의 몸체를 새로운 알고리즘으로 바꾼다. - 동기
어떤 것을 할 때건 한 가지 이상의 방법이 있게 마련이다. 그 중 어떤 것은 분명 다른 것보다 쉬울 것이다. 알고리즘에서도 마찬가지다. 어떤 것을 할 때 더 명확한 방법을 찾게 되면, 복잡한 것을 명확한 것으로 바꾸어야 한다.
- 주의사항
'Programs > Refactoring' 카테고리의 다른 글
Refactoring - 데이터 구성 (1) | 2011.11.30 |
---|---|
Refactoring - 객체간의 기능 이동 (5) | 2011.11.21 |
리팩토링(Refactoring) (4) | 2011.11.07 |