ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 6. 변수와 가독성
    Technique/Readable Code 2015. 12. 10. 22:24
    반응형

    변수를 엉터리로 사용하면 코드를 이해하기 어려워 지는 커다란 이유는 아래와 같다


    ■ 변수의 수가 많을수록 기억하고 다루기 더 어려워진다.

    ■ 변수의 범위가 넒어질수록 기억하고 다루는 시간이 더 길어진다

    ■ 변수의 값이 자주 바뀔수록 현재값을 기억하고 다루기가 더 어려워진다.


    이러한 문제를 해결하기 위하여...


    변수 제거하기

    가독성에 도움이 되지 않는 변수를 제거하는 방법들

    ■ 불필요한 임시변수

     

    1
    2
    now = datetime.datetime.now();
    root_message.last_view_time = now;
    cs

    위 코드에서 now변수는 꼭 필요한가? 그렇지 않다. 이유는

    - 복잡한 표현을 잘게 나누는 것이 아니다

    - 명확성에 도움이 되지 않는다 datetime.datetime.now는 그 자체로도 명확하다

    - 한 번만 사용되어 중복된 코드를 압축하지 않는다

    now가 없다하더라도 코드를 이해하는데 아무린 지장이 없다.


    1
    root_message.last_view_time = datetime.datetime.now();
    cs

     now의 경우 남겨진 쓰레기 같은 존재가 된다. 프로그래머 입장에서는 어디선가 사용하겟지 라고 생각하고 만들엇지만 실제론 전혀 사용되지 않는다.


    ■ 중간 결과 삭제하기

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var remove_one = function ( array, value_to_remove ){
        var index_to_remove = null;
        forvar i = 0; i < array.length; i+= 1 ){
            if( array[i] === value_to_remove ){
                index_to_remove = i;
                break;
            }
        }
     
        if( index_to_remove !== null ){
            array.splice(index_to_remove, 1);
        }
    }
    cs

    이 코드에서 index_to_remove는 불필요하게 값을 가지고 있는 셈이 된다

    이런 녀석은 굳이 따로 값일 가지는게 아니라 그 자리에서 바로바로 지워주는 게 좋다

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var remove_one = function ( array, value_to_remove ){
        var index_to_remove = null;
        forvar i = 0; i < array.length; i+= 1 ){
            if( array[i] === value_to_remove ){
                array.splice(i,1);
                return;
            }
        }
    };
    cs

    불필요한 변수를 사용해 코드를 복잡하게 하는 것 보다 이렇게 최대한 함수를 빨리 반환하는 게 좋다



    ■ 흐름 제어 변수 제거하기

     

    1
    2
    3
    4
    5
    6
    7
    boolean done = false;
     while/* 조건 */ && !done ){
        if( ... ){
            done = true;
            continue;
        }
    }
    cs

    이런 식으로 반복문을 강제로 빠져나가게 하거나, 유지시키기 위해 사용하는 변수를 흐름제어 변수 라고 한다.

    하지만 이런 녀석은 전혀 필요없다. 실제 데이터도 저장하지도 않는다!! 

    이런 흐름 제어 변수는 프로그램의 구조를 잘 설계하면 제거할 수 있다.

     

    1
    2
    3
    4
    5
    while/* 조건 */  ){
        if( ... ){
            break;
        }
    }
    cs

    중첩된 여러 루프 때문에 break가 추가로 필요하게 될 경우엔 루프안에서 반복되는 행동을 새로운 함수로 만들면 된다.


    ■ 변수의 범위를 좁혀라

    전역변수를 피하라

    전역 변수는 어디에서 어떻게 사용되는지 일일이 확인하기 어렵기 때문이다.

    전역 변수의 이름과 지역 변수의 이름이 중복되어 네임스페이스가 더러워 질 수도 있다.

    모든 변수의 범위를 좁히는 일은 언제나 좋다!

    왜냐하면 코드를 읽는 사람이 한꺼번에 생각해야 하는 변수 수를 줄여주기 때문이다.

    모든 변수의 범위를 두 배로 축소시키면 한 번에 읽어야 하는 변수의 수는 평균적으로 반으로 줄어든다.


    많은 메소드를 정적 static으로 만들어서 클래스 멤버 접근을 제한해라

    - 정적 메소드는 읽는 사람으로 하여금 이코드는 저 변수들로부터 독립적이구나 라는 인식이 생긴다

    커다란 클래스를 여러 작은 클래스로 나누는 방법

    - 작은 클래스 들이 서로 독립적일 경우 매우 유용하다.


    이러한 행위를 하는 이유는 변수를 서로 분리시켜 햇갈림을 방지하기 위함이다.


    원래의 C 프로그래밍 언어는 모든 변수의 정의가 함수나 블록의 윗부분에서 이루어 진다.

    이러한 방식은 특히 많은 변수를 가지고 있는 긴 함수 일 때 코드를 읽는 사람에게 지금 당장 사용되지 않는 변수조차 일단 염두에 두게 강제하는 방법 이므로 매우 좋지 않다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def ViewFilteredReplies(original_id):
        filtered_replies = [];
        root_message = Message.objects.get(original_id);
        all_replies  = Message.objects.select(root_id=original_id);
        root_message.view_count += 1;
        root_message.last_view_time = datetime.datetime.now();
        root_message.save();
         for reply in all_replies:
            if reply.spam_votes <= MAX_SPAM_VOTES;
                filtered_replies.append(reply)
         return filtered_replies  
    cs

    이런 코드는 읽는 사람으로 하여금 하꺼번에 세 개의 변수를 생각하게 하면서 그 사이에서 왔다갔다 하게 만드는 문제가 있다.

    제각각 사용하기 직전의 위치에 두는게 좋다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def ViewFilteredReplies(original_id):
        root_message = Message.objects.get(original_id);
        root_message.view_count += 1;
        root_message.last_view_time = datetime.datetime.now();
        root_message.save();
         all_replies       = Message.objects.select(root_id=original_id);
        filtered_replies = [];
        for reply in all_replies:
            if reply.spam_votes <= MAX_SPAM_VOTES;
                filtered_replies.append(reply)
         return filtered_replies 
    cs

     



    ■ 값을 한 번만 할당하는 변수를 선호하라

     변수들의 값이 너무 유동적으로 변화 한다면 프로그램을 따라가는 일은 더욱 어려워 진다.

    최대한 적은 횟수로 변하게 하는 것이 좋다.

    const,final등을 추천한다 


    반응형

    'Technique > Readable Code' 카테고리의 다른 글

    8. 한번에 하나씩  (0) 2015.12.11
    7.상관없는 하위 문제 추출  (0) 2015.12.11
    5. 거대판 표현을 잘게 쪼개기  (0) 2015.12.10
    4. 흐름제어  (0) 2015.12.10
    3. 주석  (0) 2015.12.09

    댓글

Designed by Tistory.