2017-04-01 1 views
2

이것은 추상적 인 질문이며 실제 코드가 없으므로 (아마도 최고의 의사 코드는 아님) 잘 검토하면 중도 화되지 않도록 의미가 있습니다. 그러나 그것은 제가 일하는 프로젝트가 이전의 조건들, 프로세스에 의존적 인 매우 선형 적이기 때문에 계속해서 저에게 제기되는 질문입니다. 그래서 ...순차 논리 및 가독성

각 논리적 작업이 이전 작업에 종속 된 일련의 논리 작업을 감안할 때 코드를 구성하는 두 가지 방법을 시도했습니다. 하나는이

Proceed = True 

If Task1 Not Successful Then 
    Proceed = False 
End If 

If Proceed Then 
    If Task2 Not Successful Then 
     Proceed = False 
    End If 
End If 

처럼 proceed 변수에 따라 달라집니다하지만이 실행 변수 접근 방식을 진행하는 효과 장소 주석의 숫자에 읽은 것은 적합하지 않습니다. 그래서 대안 나는 전자가 훨씬 더 읽을 수있는, 내 눈에

If Task1 Succcesful Then 
    If Task2 Successful 
     Then Etc 
    Else 
     Error Condition 
    End If 
Else 
    Error Condition 
End If 

을 가질 수, 논리는 매우 분명하다. 그리고 시퀀스의 작업 수가 많아지면 (실제로 3 개 이상) 중첩 된 If는 실제로 다루기 힘들어집니다. 제 질문은이 첫 번째 접근법을 사용하지 않은 이유는 무엇입니까? 가독성을 높이기 위해 두 번째 예제에서 논리를 구성하는 더 좋은 방법이 있습니까? 아니면 전자의 이슈와 전자의 이슈를 모두 다룰 수있는 세 번째 방법이 있습니까? 아니면 순차적으로 종속적 인 작업 순서가있을 때 실제로 첫 번째 접근 방식이 좋습니까?

답변

0

정말 상황에 따라 다릅니다. 더 자세한 내용은없이, 그리고 원래의 블록에 엄격하게 동등 코드를 고집, 나는 불필요한 중첩을 피함으로써 시작할 것 :

Proceed = False; 

if Task1 successful and Task2 successful Then 
    Proceed = True 
end if 

대부분의 언어에서, 당신은 단지 변수에 바로 부울을 넣을 수 있습니다.

Proceed = task1 successful and task2 successful 

당신이 정말로, 아마도 이런 식으로 피하고 선호하는 경우

: 지금까지 모든 경우에

Proceed = True; 

If Task1 not successful then 
    Proceed = False 
Else if Task2 not successful then 
    Proceed = False 
Else if Task3 not successful then 
    Proceed = False 
End if 

, 당신은 중첩 마십시오. 가독성을 위해 이것은 중요합니다.

이외에도 대체 제품에는 두 가지 변경 사항이 있습니다. 첫 번째는 "진행"변수가 완전히 삭제된다는 사실입니다. 나는 이것에 동의한다. 원래 코드의 어떤 독자는 극복해야 : 지금

초기화 X ... 지금, x는 다음 y를위한 준비하면 ... 좋아, Y

변경할 수있는 경우 이것에 :

개념적으로 쉽게 y를

x는 다음을 수행합니다.

그래서 내가 할 것이다 :

If Task1 successful and Task2 successful and Task3 successful then 
    Do your thing 
End if 

또는

If Task1 not successful then 
    Do something 
else If Task2 not successful then 
    Do some other thing 
else 
    Do your main thing 
end if 

두 번째 차이는 "에러 상태"에 넣어 것입니다. 특히 "오류"에 대해 언급합니다. 읽는 문서에서 실행을 중지하고 오류 메시지를 인쇄하는 등의 오류 처리가 필요하다고 말하면 올바른 것입니다. 비록 당신이 기회가 있다면 Task1 procedure 내부와 같이 if/then 문에 도달하기 전에 그들을 처리해야합니다. 이렇게하면 if/then 문이 단순화 될뿐만 아니라 적절한 IDE가 오류를 발생시킬 수 있으므로 코드 작성자에게는 더 나은 환경이므로 문제가 발생하자마자 바로 처리하는 것이 가장 좋습니다. 개발자는 궁극적 인 출처가 무엇인지 알기 위해 오랜 기간 추적 할 필요가 없습니다.

0

둘 다 일반적입니다. 여러 가지 방법이 순서대로 호출 할 필요 일관성있는 API로 작업 할 때 첫 번째는 특히 일반적입니다 : 당신이 둥지에 이상 2 ~ 3 단계가 필요하지 않은 경우

API_THING *thing = NULL; 
API_RESULT result = CreateThing(&thing, ...); 
if (API_OK == result) result = InitializeThing(&thing, ...); 
if (API_OK == result) result = DoThingToThing(&thing, ...); 
// ... 
if (thing) 
{ 
    ReleaseThing(&thing, ...); 
    thing = NULL; 
} 

다른 하나는 일반적이다 (특히 경우 깊은 두 경우 모두)이 처리됩니다

제시되지 않은 또 다른 하나입니다 goto 및/또는 예외 :

API_THING *thing = NULL; 
if (API_OK != CreateThing(&thing, ...)) goto CLEANUP; 
if (API_OK != InitializeThing(&thing, ...)) goto CLEANUP; 
if (API_OK != DoThingToThing(&thing, ...)) goto CLEANUP; 
//... 
CLEANUP: 
if (thing) 
{ 
    ReleaseThing(&thing, ...); 
    thing = NULL; 
} 

만약 당신이 위의 goto 예에서와 같이 수행하고 각 줄에 던질 수있는 예외를 사용하여, 또는 당신이 mig HT 던져 방법에 API를 래핑 :

void DoCreateThing(API_THING **thing, ...) 
{ 
    if (API_OK != CreateThing(thing, ...)) 
     throw new ApiException("CreateThing Failed!"); 
} 

//... 

API_THING *thing = NULL; 
try 
{ 
    DoCreateThing(&thing, ...); 
} 
catch (ApiException e) 
{ 
    // ... 
} 
// ... 
finally 
{ 
    if (thing) 
    { 
     ReleaseThing(&thing, ...); 
     thing = NULL; 
    } 
} 

테이크 마음 : 당신이 프로그래밍 권리를하고 있다면, 당신은 여기에 만들 어떤 결정을 당신이 당신의 높은 수준의 아키텍처에서의 행동이 비트를 캡슐화하는 방법만큼 중요하지 않을 것이다 .