우아한 코드를 작성하는 가장 좋은 실천

12856 단어
텍스트 링크:https://juejin.im/post/5adeaf64f265da0b9347f156
로버트 마틴은 "코드 읽기에서 욕하는 빈도가 코드 품질액을 가늠하는 유일한 기준"이라고 말한 바 있다.또한 코드의 작성법은 다른 사람이 그것을 이해하는 데 필요한 시간을 최소화해야 한다. 즉, 우리가 쓴 코드는 기계에게 보여주는 것이 아니라 사람들에게 보여주는 것이다.그렇다면 어떻게 우아한 코드를 작성합니까?사상적 차원과 구체적인 기교 차원에서 코드를 최적화할 수 있다. 사상적 차원은 대상을 대상으로 하는 디자인 원칙을 따르는 것을 가리키며 이번 호에서 소개한 것은 구체적인 기교이다.
##1. 코드는 항상 짧을수록 좋습니까?
assert((!(bucket = findBucket(key))) || !bucket.isOccupied());

위의 이 줄 코드는 비교적 짧지만 읽기가 어렵다.더욱 잘 읽기 위해서 우리는 다음과 같은 수정을 했다.
bucket = findBucket(key);
if(bucket != null){
  assert(!bucket.isOccupied());
}

코드 줄 수를 줄이는 것은 좋은 목표이지만, 코드를 읽는 이벤트를 최소화하는 것이 더 좋은 목표이다.

2. 중요 문장에 주석 추가

// Fast version of "hash = (65599*hash) + c"
hash = (hash << 6) + (hash << 16) - hash + c

위의 이 줄 코드에 주석을 추가하지 않았다면 우리는 무슨 뜻인지 전혀 몰랐을 것이다. 그러나 이 줄의 주석이 있으면 우리는 위치 이동 조작을 통해 성능을 향상시킬 수 있다는 것을 알 수 있다.
## 3. tmp의 사용 tmp는 우리가 자주 사용하는 것이다. 예를 들어 두 변수를 바꾸면 모두 약정된 것이 되었다.
tmp = right;
right = left;
left = tmp;
String tmp = user.getName();
tmp += " " + user.getPhoneNumber();
tmp += " " + user.getEmail();
template.set("user_info",tmp);

4. i, j, k,iter, it: 색인으로만 사용하거나 반복

i,j,k,iter,it 색인으로 사용되거나 순환이 반복되는 것은 이미 업계의 규범이 되었다. (i는 index의 줄임말이다). 예를 들어 다음과 같다.
for(int i=0;i<100;i++){
  for(int j=0;j<100;j++){
    ......
  }
}

Iterator iter = list.iterator();
while(iter.hasNext()){
  ......
}

만약 우리가 다른 곳에서 i, j, k를 사용한다면 읽는 사람의 시간을 증가시킬 것이다.

5. 중요 속성 첨부


우리는 명칭을 주석으로 삼아 더 많은 정보를 담을 수 있도록 한다.

6.이름은 얼마나 걸립니까?

  • 작은 역할 영역에 짧은 이름 사용하기
  • 작용역이 큰 사람은 긴 이름을 사용할 수 있다
  • if(debug){
      Map m = new HashMap<>();
      lookUpNamesNumbers(m);
      print(m);
    }
    

    7. 오해하기 쉬운 이름을 쓰지 마라

    results = Database.all_objects.filter("year<=2011")
    

    위의 코드 결과는 현재 어떤 정보를 포함하고 있습니까?Filter는 2011년보다 작은 데이터를 필터합니까?아니면 보류?

    8.min과 max로 한계를 표시하는 것을 추천합니다

    MAX_ITEMS_IN_CART = 10;
    
    if (shoppingCart.numOfItems()> MAX_ITEMS_IN_CART){
        error("Too many items in cart");
    }
    

    9.begin과end로 포함/배제 범위를 표시하는 것을 추천합니다


    begin은 포함, end는 배제를 나타낸다. 자바에서 전형적인 예는 String이다.substring()
    
    String s = "Hello world";
    
    s.substring(2,5);-> "llo"
    
    

    10. 사용자의 기대와 일치


    일반적으로 Getter 방법은 한 필드의 값을 얻는 것이다. 사용자가 기대하는 것은 경량급 방법이다. 만약 그 중에서 너무 많은 계산을 했다면 이름을 바꾸는 것을 고려해야 한다.
    
    public double getMeanPrice(){
    
    //          ,        
    
    }
    
    public double computeMeanPrice(){
    
    //          ,        
    
    }
    
    

    11. 코드 자체로 빠르게 추정할 수 있는 사실에 주석을 달지 마라

    
    public  class Account {  
    
        // Constructor
    
       public  Account(){
    
       }
    
       // Set the profit member to a new value    
    
       void setProfit(double profit){
    
             …….
    
       }   
    
        // Return the profit from this Account    
    
        double getProfit(){
    
            ….
    
        }
    
    };
    
    

    12. 나쁜 이름에 주석을 달지 마라--이름을 고쳐야 한다

    // Releases the handle for this key.This doesn't modify the actual registry.
    void deleteRegistry(RegistryKey key)
    

    언뜻 보기에 우리는 이것이 등록표를 삭제하는 함수라고 오인할 수 있지만, 주석에서 그것이 진정한 등록표를 바꾸는 것이 아니라는 것을 분명히 했다.따라서 우리는 더욱 자기 설명의 이름을 사용할 수 있다. 예를 들어 다음과 같다.
    void releaseRegistryHandle(registryKey key);
    

    13. 코드의 하자에 대한 주석 쓰기


    //TODO: 빠른 알고리즘을 사용하거나 코드가 완성되지 않았을 때//TODO(dustin): JPEG 이외의 이미지 형식 처리

    14. 상수에 대한 주석 쓰기

    // users thought 0.72 gave the best size/quality tradeoff
    image_quality = 0.72;
    
    // as long as it's >= 2*num_processors,that's good enough
    NUM_THREADS = 8;
    
    // impose a reasonable limit - no human can read that much anywhere
    const int MAX_RSS_SUBSCRIPTIONS = 1000;
    

    15. 독자의 입장에서 주석을 쓴다

    struct Recoder {
        vector<float> data;
        ......
        void clear(){
            //           ,       data.clear()
            vector<float>().swap(data);
        }
    }
    

    만약 좋은 주석이 독자의 의문을 풀 수 있다면 상술한 것을 다음과 같이 수정합니다: 강제 Vector가 메모리를 메모리 분배기에 진정으로 돌려주도록 하려면 자세한 내용은 STL swap trick을 보십시오.

    16. 가능한 트랩 게시

    void sendMail(String to,String subject,String body);
    

    이 함수는 외부 서버를 호출하여 메일을 보내야 하기 때문에 시간이 많이 걸리고 사용자의 라인이 끊길 수 있습니다.이 설명을 주석에 넣어야 합니다.

    17. 조건문에서 매개 변수의 순서


    일반 원칙: 변수를 왼쪽에 놓고 상량을 오른쪽에 놓는다.더 넓게 말하면
    비교적 안정된 변수를 오른쪽에 놓고 변화가 큰 것은 왼쪽에 놓는다.예컨대if(length>=10)는if(10<=length)가 아니다.하지만
    크기 비교가 아닌 경우에는 위의 원칙이 작동하지 않는 것 같습니다. 예를 들어 요청 매개 변수가 특정 값인지 확인하는 것입니다.if ( request.getParameterValue("name")).equals("Brandon")) 이 때 상수'Brandon'을 사용하면 빈 바늘이 생기는 것을 피할 수 있습니다(위의 매개 변수는name이 없거나 값이 비어 있지 않습니다).

    18. if/else 문 블록의 순서


    if/else 쓰기 규범: 우선 마이너스 논리가 아니라if(ok), 예를 들어if(!ok)를 처리한다.그 다음에 간단한 상황을 처리하면if와else 처리 코드가 같은 화면에서 볼 수 있도록 합니다.

    19. 조기 귀환을 통해 플러그인 감소


    미리 되돌아오는 메커니즘을 사용하면 함수의 삽입 등급을 얕게 할 수 있다.미리 되돌아오는 코드를 사용하지 않고 밤을 들다.
    static bool checkUserAuthority()
            {
                bool a, b, c, d, e;
    
                if (a)
                {
                    if (b)
                    {
                        if (c)
                        {
                            if (d)
                            {
                                if (e)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
    
                return false;
            }
    

    미리 반환된 코드 사용:
    static bool checkUserAuthority()
            {
                bool a, b, c, d, e;
    
                if (!a)
                    return false;
    
                if (!b)
                    return false;
    
                if (!c)
                    return false;
    
                if (!d)
                    return false;
    
                if (!e)
                    return false;
    
                return true;
           
            }
    

    ##20. "요약 변수"를 통해 가독성 향상
    if(request.user.id == document.owner_id){
        // user can edit this document ...
    }
    
    if(request.user.id != document.owner_id){
        // document is read-only...
    }
    

    관찰을 통해 우리는 변수final boolean user_owns_document=(request.user.id == document.owner_id)를 추출하고 코드를 다음과 같이 수정할 수 있다.
    if(user_owns_document){
     // user can edit this document ...
    }
    if(!user_owns_document){
        // document is read-only...
    }
    
    

    21. 제어 흐름 변수 감소


    while, for 등 순환 문장에서, 우리는 보통 사용자 정의bool 변수를 사용하여 흐름을 제어합니다.
    boolean done = false;
    while(/* condition */ && !done){
        ...
        if(...){
            done = true;
            continue;
        }
    }
    

    우리의 경험에 따르면'컨트롤 흐름 변수'는 프로그램 구조, 논리를 최적화하여 제거할 수 있다.
    while(/* condition */){
        ...
        if(...){
            break;
        }
    }
    

    22. 변수의 작용역을 축소한다

    void foo(){
        int i = 7;
    
        if(someCondition){
            // i is used only within this block
        }
    
    }
    
    void foo(){
        if(someCondition){
            int i = 7;
            // i is used only within this block
        }
    }
    

    23. 공유를 위해 변수를 클래스로 설정하지 마라

    public class LargeClass{
        String s;
        void method1(){
            s = ...
            method2();
        }
        void method2(){
            //  s
        }
    }
    

    매개 변수 전달을 통해 데이터 공유를 실현하다
    public class LargeClass{
        void method1(){
            String s = ...
            method2(s);
        }
        void method2(String s){
            //  s
        }
    }
    

    24. 모든 변수를 처음에 정의하지 마라


    모든 변수를 처음에는 C 언어의 스타일로 정의하고, 대상을 향한 언어 습관은 변수를 사용하기 시작한 곳에 정의합니다.
    public void foo(){
      boolean debug = false;
      String[] pvs;
      String pn;
      String pv;
      ...
    }
    

    상술한 건의를 제외하고 우리는 아리자바규범을 참고하여 위챗 신호인'나무는 커질 수 있다'를 주목하고'아리자바규범'을 보내면 관련 자료를 얻을 수 있다.
    위챗 공식 계정에 관심을 가져 주십시오: 나무는 크고 모든 문장이 공통 계정에 동기화될 것입니다.

    좋은 웹페이지 즐겨찾기