파멸의 피라미드(프로그래밍)

Pyramid of doom (programming)

컴퓨터 프로그래밍에서, 파멸의 피라미드는 프로그램이 함수에 대한 접근을 제어하기 위해 많은 수준의 중첩된 들여쓰기를 사용할 때 발생하는 일반적인 문제이다.는 늘 포인터를 확인하거나 콜백을 [1]처리할 때 흔히 볼 수 있습니다.이 용어의 두 가지 예는 JavaScript의 [2]특정 프로그래밍 스타일과 관련된 것이며, 객체 중 하나가 늘 포인터일 [3][4]때 객체 지향 프로그래밍 언어로 발생하는 if 문장의 중첩입니다.

대부분의 최신 객체 지향 프로그래밍 언어에서는 닷 표기법이라고 불리는 코딩 스타일을 사용하여 여러 메서드콜을 하나의 코드로 쓸 수 있습니다.각 콜은 마침표로 구분됩니다.예:

 = 창문들('메인").(5).크기().(); 

이 코드에는 4개의 다른 명령이 포함되어 있습니다.이 코드는 먼저 창 컬렉션에서 이름이 "Main"인 창을 검색한 후 해당 창의 뷰 컬렉션에서 5번째 서브뷰를 검색한 후 를 호출합니다.size뷰의 치수와 함께 구조물을 반환하는 메서드, 그리고 마지막으로 호출합니다.width변수 이름에 할당된 결과를 생성하는 구조상의 메서드theWidth.

이 접근법의 문제는 코드가 이들 값이 모두 존재한다고 가정한다는 것입니다.창에 크기가 있고 크기가 너비가 있을 것으로 예상하는 것은 타당하지만, "Main"이라는 이름의 창이 존재하거나 5개의 하위 보기가 있다고 가정하는 것은 전혀 타당하지 않습니다.이러한 전제 조건 중 하나가 잘못된 경우 null에서 메서드 중 하나가 호출되어 null 포인터 오류가 발생합니다.

이 오류를 피하기 위해 프로그래머는 모든 메서드콜을 체크하여 값을 반환하는지 확인해야 합니다.같은 코드의 안전한 버전은 다음과 같습니다.

한다면 창문들.포함하다('메인") {     한다면 창문들('메인")..포함하다(5) {          = 창문들('메인").(5).크기().();         //Width에서 동작하는 추가 코드     } } 

프로그래머가 그 값이 존재하는지 여부와 유효하지 않은지에 따라 그 값을 사용하기를 원하는 경우, 그 값의 내부 기능 코드는if문장은 모두 오른쪽으로 밀리기 때문에 긴 줄을 읽기가 어렵습니다.이로 인해 종종 코드를 "평탄화"하려는 시도가 발생합니다.

한다면 창문들.포함하다('메인") { 윈도 = 창문들('메인") } 한다면 윈도 != 무효 & & 윈도..포함하다(5) { 표시 = 윈도.(5) } 한다면 표시 != 무효 {      = 표시.크기().();     //표준 코드 } 

또는 다음 중 하나:

한다면 !창문들.포함하다('메인") {     // 핸들 오류 } 또 다른 한다면 !창문들('메인")..포함하다(5) {     // 핸들 오류 } 또 다른 {      = 창문들('메인").(5).크기().();     //Width에서 동작하는 추가 코드 } 

이런 종류의 프로그래밍 구성은 매우 흔하며 많은 프로그래밍 언어들이 이것을 다루기 위해 일종의 통사설탕을 첨가했다.예를 들어, 애플의 Swift는 if[5] 스테이트먼트에 옵션 체인의 개념을 추가한 반면, Microsoft의 C# 6.0과 Visual Basic 14null-conditional 연산자를 추가했습니다.?.그리고.?[각각 멤버 액세스와 인덱스에 사용됩니다.[6][7][8]기본 개념은 멤버 중 하나가 늘일 경우 메서드콜 문자열이 즉시 늘을 반환할 수 있도록 하는 것입니다.다음은 예를 제시하겠습니다.

 = 창문들('메인")?.(5)?.크기.; 

null을 할당한다.theWidth"Main" 또는 다섯 번째 하위 뷰 중 하나가 누락된 경우 문을 완료하고 너비를 반환합니다.프로그래머가 이 두 경우에 다른 행동을 취하기를 원하는 많은 시간이 있습니다, 그래서 Swift는 이 역할을 위해 통사 설탕의 또 다른 형태를 추가합니다.if let"옵션 바인딩"이라고도 하는 스테이트먼트:

한다면 허락하다 표시 = 창문들('메인")?.(5) {     //뷰가 존재하는 것을 알고 작업을 수행합니다.      = 표시.크기. } 

결의안

피라미드 오브 둠은 보통 코드를 여러 개의 중첩된 함수(또는 다른 그룹화)로 분할하는 것만으로 모든 언어로 해결할 수 있습니다.예를 들어 다음과 같은 경우:

주된() {  () {   bbbb() {     ccc() {     Ddddd.() {      // 지금 바로 실행     }    }    }  } } 

다음과 같이 기능을 분류할 수 있습니다.

어떻게 좀 해봐.() {  // 지금 바로 실행 }  참조() {  ccc() {   Ddddd.() {    어떻게 좀 해봐.()   }  } }  주된() {  () {   bbbb() {    참조()   }  } } 

마찬가지로 유사한 피라미드가 발생할 경우 데이터 구조를 수준별로 분류할 수 있습니다.

파멸의 피라미드가 해결되었을 뿐만 아니라, 크고 복잡한 기능은 갖지 않는 것이 좋습니다.작은 기능은 올바른 기능을 얻기 쉽고, 읽기 쉽고, 조작을 검증하기 쉽습니다.각 레벨의 기능명을 선택하는 것도, 독자에게 어디에서 행해지는지를 명확하게 하는 데 도움이 됩니다.일반적으로 각 레벨은 멀리 있는 레벨에 접속할 필요가 없기 때문에 분리하기가 쉽습니다.이러한 연관성이 있다면, 저자는 그들의 디자인을 보다 신뢰할 수 있는 것으로 다시 생각할 수 있다. 왜냐하면 이것은 버그의 비옥한 원천이기 때문이다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ Dave Herman (14 December 2011). "Why coroutines won't work on the web". The Little Calculist. Archived from the original on 2016-03-06.
  2. ^ "The Pyramid of Doom: A javaScript Style Trap". 27 November 2012. Archived from the original on 2015-12-09.
  3. ^ Eberhardt, Colin (8 December 2014). "Tearing Down Swift's Optional Pyramid Of Doom". Archived from the original on 2016-07-31.
  4. ^ "New Language Features in Visual Basic 14". 9 December 2014. Archived from the original on 2014-12-25.
  5. ^ "Optional Chaining". Apple.
  6. ^ "Null-conditional Operators (C# and Visual Basic)". Microsoft.
  7. ^ "What's New for Visual C#". Microsoft.
  8. ^ "What's New for Visual Basic". Microsoft.
  9. ^ Joe Zimmerman (March 28, 2013). "What's The Point Of Promises?". telerik.com.

[1]