2009-12-14 1 views
3

이것은 지금 당분간 제게 당황 스럽습니다.아무런 해를 끼치 지 않아도 코드가 논리적으로 유효하지 않은 호출을 예방해야합니까?

리소스를 나타내는 클래스를 상상해 보겠습니다.이 리소스를 사용하려면 먼저 리소스에 '열기'메서드를 호출해야합니다. 그렇지 않으면 InvalidOperationException이 throw됩니다.

내 코드가 이미 열려있는 리소스를 열거 나 이미 닫힌 리소스를 닫으려고 시도하는지 확인해야합니까?

해를 끼치 지 않아도 논리적으로 유효하지 않은 호출을 방지해야합니까?

이 방법으로 프로그래밍하면 다른 쪽에서 코드를 작성하는 데 도움이 될 것이라고 생각하지만 너무 많은 책임을지고 재사용에 영향을 줄 수 있다고 생각합니다.

너희들은 어떻게 생각하니?

편집 :

나는 그것이 가능한 잘못된 사용 중 미끄러하지 않기 때문에 이것은 방어 프로그램 호출 할 수 있다고 생각하지 않으며, 다른 경우 InvalidOperationException이 발생합니다.

답변

6

defensive programming입니다. 응용 프로그램이 잘못된 행동으로 인해 충돌하지 않도록하기 때문에 좋은 프로그래밍 방법입니다.

다른 메서드가 호출되기 전에 어떤 메서드를 먼저 호출해야한다는 것은 좋은 프로그래밍 습관이 아닙니다. 그것은 복잡성이 많아 클래스 자체가 더 잘 처리합니다.

sequential coupling이라고합니다. 이 wikipedia 기사는 그것이 나쁜 습관이라면 상황에 달려 있다고 말합니다. 그러나 부적절하게 처리 될 때 충돌하지 않아야합니다. 때로는 일을 명확하게하기 위해 예외를 던질 필요가 있습니다.

+0

글쎄요. 남용 가능성이있을 때 충돌을 막기 위해 방어 프로그래밍을 사용합니다 (이는 인터페이스 반대편에서 unknwon (ab) 사용자와 인터페이스 할 때마다 발생 함). 그러나 OP는 아무 일도 일어나지 않았으므로 학대를 처리해야한다고 질문했다. 나는 동의하지 않는다 - 사용자는 코드 (오류 코드, 주장 또는 예외 임)에 문제가 있음을 알려야한다. 간단히 말해서 : (방어 프로그래밍을 사용하여) 처리하지만 알려줍니다. 제비 또는 충돌 및 API 사용자는 당신을 미워할 것입니다. – MaR

+0

나는 그 오류를 삼키는 것에 관해 아무 말도하지 않았다. 오류가 발생했을 때이를 인식하고 적절한 조치를 취해야합니다. – Ikke

+0

흥미로운 점은 나쁜 관행에 대해 더 많은 정보를 찾을 수 있습니까? – Trap

2

예제가 실제로 필요한 경우 열기 기능은 클래스 생성자에 의해 호출되어야합니다.

C++ iostream 라이브러리 (매우 널리 사용되고 있으며 아주 좋은 예가 될 수 있음)를 고려하면 스트림 클래스가 열려 있는지 여부에 관계없이 모든 작업을 호출 할 수 있습니다. 호출 된 함수는 작업을 수행 할 수없는 경우 일종의 오류 표시기를 반환합니다. 물론 함수는 스트림 상태를 테스트해야합니다.

당신이해서는 안되는 일은 프로그램이 이전 입력을 매개 변수로 자동으로 허용하도록 허용하는 것입니다. 예를 들어,이

int strlen(const char * s) 
{ 
    if (s == 0) 
    { 
     return 0;  // bad 
    } 
    else 
    { 
     // calculate length not shown 
    } 
} 

이 소란을 유발하지 않으면 서 나쁜 입력 필드로 나 strlen()

의 깨진 구현 될 것 - 대신 정확한 개발 철학에 따라) (예외를 던지거나 어설를 사용해야합니다.

+0

열기/닫기 기능은 자원을 등록 및/또는 선언 할 수 있지만 소비 될 때까지 완전히 초기화되지 않기를 바라기 때문에 가능합니다. 나는 게으른 초기화의 생각을 좋아하지만 그냥 닫기 함수를 남겨주세요 :) – Trap

+0

이것은 사실 C++ 파일 스트림 객체가 어떻게 작동하는지입니다. 생성시 또는 나중에 open() 멤버를 사용하여 열 수 있습니다. 그러나 두 경우 모두 (열려 있거나 없거나) 스트림은 항상 유효한 상태입니다. –

1

맛, 재능 및 경험을 대신하여 조직의 코드에 얼마나 많은 안전성 검사가 있어야 하는지를 알아낼 수 없습니다.

양질의 API는 바보가 아니며 적절한 경고량으로 사용자를 안내합니다.

때때로 안전 예방 조치는 성능을 저하시킬 수 있습니다. 성능은 프로그래밍에서 가장 반 직관적 인 것들 중 하나입니다. 성능이 중요한 경우에만주의해서 최적화하십시오.

3

이것은 실제로 클래스가 실제로 무엇을하는지에 따라 다릅니다. 경우에 따라 자동으로 작동하지 않는 것이 좋습니다 (예 : DVD 플레이어를 계속 작동 시키거나 이미 열려있는 DVD 트레이를 열면 오류 메시지가 표시되지 않음). 가능한 한 많은 정보를 원할 경우 비행기가 이미 닫혀있는 문을 닫으려고하면 뭔가 잘못되어 조종사에게 경고해야합니다.

논리적으로 유효하지 않은 작업이 수행 될 때 대부분의 경우 오류를 던지는 것은 개발자에게 유용하기 때문에 예외를 구현하는 것은 누가 코드를 사용할 것인가에 달려 있습니다. 한 응용 프로그램에 대해 내부적으로 사용되는 경우 중요하지 않습니다. 그러나 여러 다른 프로젝트 나 개발자가이 파일을 사용한다면 그 파일을 조사 할 것입니다.

1

공개되는 공개 SDK의 일부인 경우 공개 된 API 호출은 강력한 유효성 검사가 있어야합니다. '사용자'(개발자)를 돕고 지원하지 않으려는 지원 사용에 지장이 없도록 보장합니다.

그렇지 않으면 수표를 추가하지 않겠습니다. 나는 그들이 코드를 읽기가 더 어렵게 만들고 이러한 검사가 거의 테스트되지 않는다고 생각한다. 과거에는 내 코드가 잘못된 일을하지 않도록이 코드를 많이 추가했습니다. 이제 코드가 올바른지 확인하기 위해 단위 테스트를 작성합니다. 차이점? 테스트는보다 관리하기 쉽고 읽기 쉽고 프로덕션 코드가 복잡하지는 않습니다.

1

이미 열려있는 파일을 여는 경우, 요청의 영향을 알고 있는가에 달려 있습니다. 예를 들어 현재 읽은 위치를 재설정합니다.

이미 닫힌 파일을 닫는 경우 알려진 상태로 만들 파일에 대한 요청으로 생각하십시오. 코드는 아무 것도 할 필요가 없지만 코드가 성공 조건을 반환 할 수 있도록 원하는 상태가 유지됩니다. 모뎀 버퍼/직렬 포트 또는 프린터/스풀러와 같이 조정할 수있는 파일 버퍼링이 있거나 처리 할 필요가있는 링크 된 리소스가있는 경우에는 그렇지 않습니다.

부작용을 포함하여 원하는 결과로 되돌아 가서 문제를 생각해보십시오.

로그인 상태에 관계없이 표시되는 앱 메뉴에 '로그 아웃'링크를 넣었습니다. 왜? 로그인 화면에서 로그인 화면으로 돌아가는 것을 처리하는 간단한 (그리고 매우 짧은) 방법을 사용하고 로그인 상태를 추적하는 많은 수표를 저장 했으므로 '로그 아웃'메뉴 항목은 당신은 로그인했다.

+0

IMO, 사용자가 이미 닫힌 스트림을 닫으려고하면 내 자신의 상태를 너무 게으른 지 또는 내 코드에 비합리적인지 여부를 알 수 있습니다. 가까운 작업을 요청하려면 RequestClose()를 호출하고 이벤트가 발생할 때까지 기다리십시오. :) – Trap

1

논리적 잘못된 호출은 항상 디버그 모드에서 사용자에게보고해야합니다 ..

릴리스 모드에서 컴파일

, 코드가 불필요한 예외를 발생 또는를 위험에 빠뜨릴 수있는 다른 작업을 수행해서는 안 전체 응용 프로그램. 개인적으로 필자는 일종의 로그 파일을 선호하며 그러한 논리적으로 잘못된 호출을 로깅하는 것은 아무런 해를 끼치 지 않을 것입니다 (최소한 성능이 중요하지 않을 때 최소한).

관련 문제