E D R , A S I H C RSS

Replace Temp With Query

어떤 수식의 결과값을 저장하기 위해서 임시변수를 사용하고 있다면,

수식을 뽑아내서 메소드로 만들고, 임시변수를 참조하는 곳을 찾아 모두 메소드 호출로 바꾼다. 새로 만든 메소드는 다른 메소드에서도 사용될 수 있다.


    double basePrice = _quantity * _itemPrice;
    if (basePrice > 1000)
        return basePrice * 0.95;
    else
        return basePrice * 0.98;

를 다음과 같이 작성한다.

    if (basePrice() > 1000)
        return basePrice() * 0.95;
    else
        return basePrice() * 0.98;
...

double basePrice() {
    return _quantity * _itemPrice;
}

위의 예는 매우 극단적으로 보일지도 모른다. 하지만 위의 예를 매우 복잡한 시스템의 일부분이라 가정하고 생각해보길 바란다. 임시변수를 사용하는 코드는 해당 블럭에서만 접근 가능하기 때문에, 길어지는 성향이 있다. 이러한 임시변수를 질의 메소드(query method)로 바꿈으로써 어느곳에서라도, 임시변수에서 사용될 정보를 얻을 수 있고, 클래스 코드는 더 깔끔해진다.

그러나,

프로그래밍 경력이 있는 사람일수록, 이러한 사실에는 동의를 하지만 퍼포먼스를 우려해서 꺼리는 경향이 있다. '동일한 연산을 왜 이렇게 수행하는거지?' , '이러한 블럭은 지역적이기 때문에 임시 변수 사용은 문제가 되지 않아!' .

하지만,

그러한 우려는 ' 단지 그럴지도 모른다. ' 라는 가정일 뿐이다. 누구도 실제로 프로파일링(profiling)해보기 전까지는 알 수 없다. 실제로 문제가 되는지 아닌지는.

어느정도 수준에 오른 프로그래머일수록, 반복적으로 사용되는 값에 대해 임시변수를 사용하고 이러한 최적화(?)를 나름대로 수행하려 한다. 그러나, 이러한 미시적인 최적화는 결과적으로 거시적 최적화의 기회를 박탈하게 한다. 심지어 최악의 경우라도 임시변수를 다시 넣는 일은 쉽다(물론, 프로파일링 ' 결과 ', ' 실제로 ' 퍼포먼스에 심각한 문제를 주는 경우라면).


이러한 방법을 사용하면서 부가적으로 얻을 수 있는 장점이 하나 더 있다. 실제로 도움이 될지 안될지 모르는 최적화를 하는데 쏟는 시간을 절약할 수 있다. 임시변수 사용뿐 아니라 이러한 미세한 부분의 조정은, 해놓고 보면 별로 위대해보이지 않는 일을, 할때는 알지 못하고 결국 시간은 낭비한게 된다. 돌이켜보면 나의 이러한 노력이 제대로 효과가 있었는지도 모른다. 왜? 프로파일링 해보지 않았으니까. 단순히 시스템을 더 빨리 돌릴 수 있을지도 모른다는 우려에서 작성한 것이었으니까. DoTheSimplestThingThatCouldPossiblyWork

개인적으로 리펙토링 서적을 읽다가 상당한 충격을 받았다. 옳은 방법이라고 생각한 내용이 실제는 옳을지도 모른다라는 사실이었고, 하나의 나무를 잘 키우면 전체적으로도 득이 된다라고 생각한 내용이 실제로는 더 큰 가능성을 보지 못하게하는 잘못된 습관이었다는 사실이 나를 온통 흔들어 놓았다. 다시 걸음마를 시작하게 된 느낌이다. 자신을 항상 바닷가에서 조개를 줍는 어린아이에 비유하던 Isaac Newton의 이야기가 떠오른다.

I do not know what I may appear to the world, but to myself I seem to
have been only a boy playing on the seashore, and diverting myself in
now and then finding a smoother pebble or a prettier shell than
ordinary. Whilst the great ocean of truth lay all undiscovered before me.
--Isaac Newton

--이선우


Refactoring
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2013-11-22 15:21:52
Processing time 0.1867 sec