티스토리 뷰

예. 이것은 가독성을 분명히 떨어 뜨립니다. 다음 코드의 문제점은 무엇입니까?

int skipFooBarIndex(String[] list){
    if(list.length >= 1 && list[0].equals(SKIP_FIRST)) 
            return 1;
                if(list.length >= 2 && (list[0] + "/" + list[1]).equals(SKIP_SECOND))
                        return 2;
                            return 0;
                            }
                            

이해하기 훨씬 쉽습니다. 일반적으로 하위 표현식의 평가 순서에 의존하므로 표현식에 부작용이있는 것은 권장되지 않습니다.

"영리한"코드로 간주한다고 가정 할 때 Brian Kernighan의 인용문을 항상 기억하는 것이 좋습니다.

디버깅은 처음에 코드를 작성하는 것보다 두 배 더 어렵습니다. 따라서 코드를 가능한 한 영리하게 작성하면 정의에 따라 코드를 디버깅 할만큼 똑똑하지 않은 것입니다.

-------------------

...하지만 내 동료들은 이것을 매우 싫어했습니다 ...

네, 그렇습니다. 그렇게 코딩 할 수 있기 때문이 아니라 그래야합니다.

그 코드 조각은 결국 누군가에 의해 유지되어야한다는 것을 기억하십시오 (누군가가 8 개월 안에 당신 자신이 될 수 있습니다).

if, make 내부의 상태를 변경하는 것은 읽고 이해하기가 더 어렵습니다 (대부분 일반적이지 않기 때문에)

Martin Fowler 인용 :

모든 바보는 컴퓨터가 이해할 수있는 코드를 작성할 수 있습니다. 좋은 프로그래머는 인간이 이해할 수있는 코드를 작성합니다.

-------------------

그렇게하지 않는 훌륭한 이유가 있습니다. 코드를 이해하고 추론하기가 정말 어렵습니다.

-------------------

문제는 코드가 코드 검토 세션에서 다중 WTF를 생성한다는 것입니다. 사람들을 "기다려, 뭐?" 가야합니다.

읽기 쉬운 코드에서도 버그를 만드는 것은 슬프게도 쉽습니다. 더 쉽게 만들 이유가 없습니다.

-------------------

예, 코드를 검토 할 때 부작용을 따르기가 어렵습니다.

그것을해야하는 이유에 관하여 : 아니오, 그것을 할 실제 이유가 없습니다. 나는 아직 아무런 손실없이 부작용없이 다시 쓸 수없는 if 문을 우연히 발견하지 못했습니다.

-------------------

그것의 유일한 잘못된 점은 그것을 쓰지 않은 사람들이 그것을 알아내는 동안 적어도 1 분 동안은 낯설고 혼란 스럽다는 것입니다. 더 읽기 쉽게 만들기 위해 다음과 같이 작성합니다.

if (list.length >= 1 && list[0].equals(SKIP_FIRST)) {
    return 1;
    }
    
    if (list.length >= 2 && (list[0] + "/" + list[1]).equals(SKIP_SECOND)) {
        return 2;
        }
        
-------------------

cppreference.com 에서 차용 :

연산자 우선 순위와 관련된 C ++의 중요한 측면 중 하나는 식의 평가 순서 및 부작용 순서입니다. 어떤 상황에서는 일이 발생하는 순서가 정의되지 않았습니다. 예를 들어, 다음 코드를 고려하십시오.

float x = 1;
x = x / ++x;

x의 값은 컴퓨터가 나눗셈의 왼쪽 또는 오른쪽을 먼저 평가해야하는지 여부가 명확하지 않기 때문에 여러 컴파일러에서 일관성이 보장되지 않습니다. 어느 쪽이 먼저 평가되는지에 따라 x는 다른 값을 가질 수 있습니다.

또한 ++ x는 x + 1로 평가되지만 실제로 x에 새 값을 저장하는 부작용은 다른 시간에 발생할 수 있으며 결과적으로 x에 대해 다른 값이 생성 될 수 있습니다.

결론은 위와 같은 표현이 끔찍하게 모호하며 어떤 대가를 치르더라도 피해야한다는 것입니다. 확실하지 않은 경우 단일 모호한 식을 여러 식으로 분리하여 평가 순서가 올바른지 확인합니다.

-------------------

이것은 해로운 행위입니까?

확실히 맞아요. 코드는 이해하기 어렵습니다. 저자를 제외한 누구에게나 두세 번 정도 읽어야합니다. 이해하기 어렵고 이해하기 쉬운 더 간단한 방법으로 재 작성할 수있는 코드는 그런 식으로 재 작성해야합니다.

당신의 동료들은 절대적으로 옳습니다.

그럴 이유가 있습니까?

이와 같은 작업을 수행 할 수있는 유일한 이유는 응용 프로그램을 광범위하게 프로파일 링했으며 코드의이 부분이 심각한 병목 현상임을 발견했기 때문입니다. 그런 다음 위의 혐오감을 구현하고 프로파일 러를 다시 실행하여 성능이 실제로 향상된다는 것을 발견했습니다.

-------------------

글쎄, 나는 무슨 일이 일어나고 있는지 깨닫지 못하고 위의 내용을 읽는 데 시간을 보냈습니다. 그래서 나는 그것이 이상적이지 않다고 분명히 제안 할 것입니다. 난 정말하지 않을 변화 상태에있는 경우 () 문 자체를 기대합니다.

-------------------

나는 아주 좋은 이유없이 부작용이있는 if 조건을 추천하지 않을 것입니다. 저에게이 특별한 예는 무슨 일이 일어나고 있는지 알아 내기 위해 여러 번 살펴 보았습니다. 확실히 생각할 수 없지만 그렇게 나쁘지 않은 경우가있을 수 있습니다.

-------------------

이상적으로는 각 코드가 한 가지 일을해야합니다. 두 가지 이상의 작업을 수행하는 것은 잠재적으로 혼란스럽고 혼란스러운 것은 코드에서 원하지 않는 것입니다.

if 문의 조건에있는 코드는 부울 값을 생성해야합니다. 값을 할당하는 작업은 두 가지 작업을 수행하는 것이며 일반적으로 좋지 않습니다.

더욱이 사람들은 조건이 단지 조건 일 것으로 기대하고 코드가 수행하는 작업에 대한 인상을받을 때 종종 조건을 훑어 봅니다. 그들은 필요하다고 결정할 때까지 모든 것을 조심스럽게 파싱하지 않습니다.

내가 검토중인 코드에 그것을 고정하고 결함으로 표시하겠습니다.

-------------------

여러 반환을 피하기 위해 삼항을 얻을 수도 있습니다.

int skipFooBarIndex(String[] list) {
    return (list.length > 0 && list[0].equals(SKIP_FIRST)) ? 1 :
           ((list.length > 1 && (list[0] + "/" + list[1]).equals(SKIP_SECOND)) ? 2 : 0);
           }
           

이 예제는 가독성이 떨어집니다.

-------------------

유지 보수 프로그래밍을 많이하는 사람으로 말하면 : 만약 내가 이것을 발견하면 나는 당신을 저주하고 울고 그것을 바꿀 것입니다.

이와 같은 코드는 악몽입니다. ​​두 가지 중 하나를 외칩니다.

  1. 저는 여기 새로 왔고 올바른 일을하는 데 도움이 필요합니다.
  2. 코드 줄을 저장했거나 컴파일러를 속여서 더 빨리 만들었 기 때문에 나는 매우 영리하다고 생각합니다. 영리하지 않고 최적이 아니며 재미 있지 않습니다.

;)

-------------------

C에서는 if 문 내부에서 상태를 변경하는 것이 일반적입니다. 일반적으로 이것이 허용되는 위치에 대해 작성되지 않은 몇 가지 규칙이 있음을 발견했습니다. 예를 들면 다음과 같습니다.

  • 변수를 읽고 결과를 확인하고 있습니다.

    int a;
        ...
        if ((a = getchar()) == 'q') { ... }
        
  • 값 증가 및 결과 확인 :

    int *a = (int *)0xdeadbeef;
        ...
        if (5 == *(a++)) { ... }
        

허용되지 않는 경우 :

  • 변수에 상수를 할당합니다.

    int a;
        ...
        if (a = 5) { ... } // this is almost always unintentional
        
  • 혼합 및 일치하는 사전 및 사후 증가단락을 :

    int a = 0, b;
        ...
        if (b || a++) { ... }    // BAD!
        

어떤 이유로 코드로 표시하려는 섹션의 글꼴은 SO에서 고정 너비가 아니지만 고정 너비 글꼴에서는 if표현식 내부의 할당 이 합리적이고 명확한 상황이 있습니다 .



출처
https://stackoverflow.com/questions/1800377
댓글
공지사항
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31