문제

코드가 얼마나 방어 해야하는지에 대해 동료 중 한 명과 토론했습니다. 나는 모두 프로 방어 프로그래밍이지만 어디를 중지 해야할지 알아야합니다. 우리는 다른 사람들이 유지할 프로젝트를 진행하고 있지만 이것이 개발자가 할 수있는 모든 미친 일을 확인해야한다는 의미는 아닙니다. 물론 그렇게 할 수는 있지만 코드에 큰 오버 헤드가 추가됩니다.

선을 어디에서 그리는지 어떻게 알 수 있습니까?

도움이 되었습니까?

해결책

나는 이것에 답할 수있는 방법이 실제로 있다는 것을 모른다. 그것은 당신이 경험에서 배우는 것입니다. 잠재적 인 문제가 얼마나 흔한 지 스스로에게 물어보고 판단 전화를해야합니다. 또한 당신이 반드시 필요하지 않다고 생각하십시오 가지다 항상 방어 적으로 코드. 때로는 코드 문서의 잠재적 인 문제에 주목하는 것이 허용됩니다.

그러나 궁극적으로, 나는 이것이 사람이 직관을 따라야하는 것일 뿐이라고 생각합니다. 옳고 그른 방법은 없습니다.

다른 팁

무엇이든 사용자 직접 또는 간접적으로 들어와야합니다 언제나 위생 점검. 그 외에도 몇 가지 assert여기에있는 곳과 거기에 아프지는 않지만, 당신은 어쨌든 미친 프로그래머 편집 및 파괴에 대해 많은 것을 할 수는 없습니다!-)

언어에 따라 코드에 넣은 방어량을 바꾸는 경향이 있습니다. 오늘 저는 주로 C ++에서 일하고 있으므로 내 생각이 그 방향으로 표류하고 있습니다.

C ++에서 작업 할 때는 충분한 방어 프로그래밍이있을 수 없습니다. 나는 내 코드를 핵 비밀을 지키고있는 것처럼 취급하고 다른 모든 프로그래머는 그들을 얻기 위해 나옵니다. 주장, 던지기, 컴파일러 시간 오류 템플릿 해킹, 인수 검증, 포인터 제거, 깊이 코드 검토 및 일반 편집증은 모두 공정한 게임입니다. C ++는 내가 사랑하고 심각하게 불신을하는 악한 훌륭한 언어입니다.

나는 "방어 프로그래밍"이라는 용어의 팬이 아닙니다. 나에게 그것은 다음과 같은 코드를 제안합니다.

void MakePayment( Account * a, const Payment * p ) {
    if ( a == 0 || p == 0 ) {
       return;
    }
    // payment logic here
}

이것은 잘못되고 잘못되었지만 잘못되었지만 수백 번 보았을 것입니다. 이 기능은 처음에는 널 포인터로 호출되어서는 안되며 조용히 받아들이는 것은 완전히 잘못입니다.

여기서 올바른 접근법은 논쟁의 여지가 있지만 최소한의 해결책은 어설 싱을 사용하거나 예외를 던지면 시끄럽게 실패하는 것입니다.

편집하다: 나는 여기서 다른 답변과 의견에 동의하지 않습니다. 모든 기능이 매개 변수를 확인해야한다고 생각하지 않습니다 (많은 기능에 대해 불가능합니다). 대신, 나는 모든 함수가 허용 가능한 값을 문서화하고 다른 값이 정의되지 않은 동작을 초래할 것이라고 진술해야한다고 생각합니다. 이것은 C 및 C ++ 표준 라이브러리 인 가장 성공적이고 널리 사용되는 라이브러리가 취한 접근법입니다.

이제 다운 보트를 시작하게하십시오 ...

구성 요소의 공개 API를 작업하는 경우 많은 양의 매개 변수 검증을 수행 할 가치가 있습니다. 이로 인해 모든 곳에서 검증을하는 습관이 생겼습니다. 그것은 실수입니다. 이 모든 검증 코드는 결코 테스트되지 않으며 잠재적으로 시스템을 필요로하는 것보다 더 복잡하게 만듭니다.

이제 단위 테스트로 검증하는 것이 좋습니다. 외부 소스에서 나오는 데이터에 대해서는 유효성 검사가 반드시 발생하지만 비외 개발자의 호출은 아닙니다.

나는 항상 내 가정을 할당합니다.

나의 개인 이데올로기 : 프로그램의 방어 성은 잠재적 인 사용자 기반의 최대 순진/무지에 비례해야합니다.

API 코드를 소비하는 개발자에 대한 방어는 일반 사용자에 대한 방어와 다르지 않습니다.

  • 매개 변수가 적절한 범위 내에 있고 예상 유형인지 확인하십시오.
  • 이루어질 수있는 API 호출 수가 귀하의 서비스 약관 내에 있는지 확인하십시오. 일반적으로 스로틀링이라고하는 것은 일반적으로 웹 서비스 및 비밀번호 점검 기능에만 적용됩니다.

그 외에도 문제가 발생한 경우 앱이 잘 회복되고 개발자에게 항상 충분한 정보를 제공하여 진행 상황을 이해하도록해야 할 일이 많지 않습니다.

방어 프로그래밍은 설계 별 코딩 방식.

다른 두 사람은입니다

  • 총 프로그래밍 그리고
  • 공칭 프로그래밍.

물론 당신은 자신을 방어해서는 안됩니다 모든 미친 것 개발자는 할 수 있지만, 그러면, 당신은 wich 맥락에서 전제 조건을 사용하여 예상되는 일을 할 것입니다.

//precondition : par is so and so and so 
function doSth(par) 
{
debug.assert(par is so and so and so )
//dostuf with par 
return result
}

테스트를 만들고 있는지 여부에 대한 문제를 제기해야한다고 생각합니다. 코딩에서 방어 적이어야하지만 Jaredpar가 지적한대로 사용하는 언어에 달려 있다고 생각합니다. 관리되지 않는 코드라면 매우 방어 적이어야합니다. 그것이 관리되면 약간의 Wiggleroom이 있다고 생각합니다.

테스트가 있고 다른 개발자가 코드를 멸망 시키려고하는 경우 테스트가 실패합니다.. 그러나 다시 코드의 테스트 범위에 따라 다릅니다 (있는 경우).

나는 방어 이상의 코드를 쓰려고하지만 적대적으로 적대적인 코드를 쓰려고 노력합니다. 무언가 잘못되고 고칠 수 있다면, 나는 할 것이다. 그렇지 않은 경우 예외를 던지거나 전달하여 누군가에게 문제를 일으킨다. 파일 시스템, 데이터베이스 연결, 네트워크 연결 (네트워크 연결)과 상호 작용하는 것은 실패하기 쉬운 것으로 간주되어야합니다. 이러한 실패를 예상하고 덫을 놓는 것이 중요합니다

이 사고 방식이 있으면 핵심은 접근 방식에서 일관성을 유지해야합니다. 통화 체인에서 문제를 해결하기 위해 상태 코드를 백업하거나 예외를 좋아할 것으로 예상합니까? 혼합 모델은 당신을 죽이거나 적어도 당신을 마시도록합니다. 무겁게. 누군가 ELSES API를 사용하는 경우 이러한 것들을 사용하는 용어로 트랩/보고하는 메커니즘으로 분리하십시오. 이 랩핑 인터페이스를 사용하십시오.

여기서 논의가 미래 (아마도 악의적이거나 무능한) 관리자에 대해 방어 적으로 코딩하는 방법이라면, 당신이 할 수있는 일에는 한계가 있습니다. 테스트 범위를 통해 계약을 시행하고 귀하의 가정을 주장하는 데있어 자유롭게 사용하는 것은 아마도 최선을 다할 수 있으며, 이는 이상적으로 코드를 혼란스럽게하지 않고 미래의 비 이주성 관리자를 위해 작업을 더 어렵게 만들어야합니다. 암호. Asserts는 읽고 이해하기 쉽고 주어진 코드의 가정이 무엇인지 명확하게 설명하므로 일반적으로 좋은 생각입니다.

사용자 조치에 대한 방어 적으로 코딩하는 것은 전적으로 또 다른 문제이며, 내가 사용하는 접근법은 사용자가 나를 얻을 것이라고 생각하는 것입니다. 모든 입력은 내가 관리 할 수있는 한 신중하게 검사되며, 코드가 안전 해지도록 모든 노력을 기울이고 있습니다. 엄격하게 조사되지 않은 상태를 유지하지 말고, 가능한 경우, 가능한 경우 우아하게 종료 할 수있는 곳 등을 유지하지 마십시오. 외부 에이전트가 코드에 가해 질 수있는 모든 Bozo 물건에 대해 생각하면 올바른 사고 방식을 얻습니다.

플랫폼이나 다른 모듈과 같은 다른 코드에 대해 방어 적으로 코딩하는 것은 사용자와 정확히 동일합니다. OS는 항상 부적절한 시간에 스레드를 교환하고, 네트워크는 항상 잘못된 시간에 사라질 것이며, 일반적으로 구석 구석에 악이 있습니다. 모든 잠재적 인 문제에 대해 코딩 할 필요는 없습니다. 유지 보수 비용은 안전의 증가에 가치가 없을 수도 있지만, 그것에 대해 생각하는 것은 아프지 않습니다. 그리고 당신이 생각한 시나리오가 있지만 어떤 이유로 든 중요하지 않은 것으로 간주되는 경우 코드에 명시 적으로 댓글을 달 때 아프지 않습니다.

시스템은 방어 점검이 발생하는 곳에서 잘 설계된 경계를 가져야합니다. 사용자 입력이 검증 된 위치 (경계에서) 및 기타 잠재적 방어 문제가 확인 해야하는 경우 (예 : 타사 통합 지점, 공개적으로 사용 가능한 API, 규칙 엔진 상호 작용 또는 다른 프로그래머 팀이 코딩 한 다른 장치에 대한 결정이 있어야합니다. ). 많은 경우에 건조를 위반하는 것보다 더 방어적인 점검을하고, 거의 베니피이트에 대한 유지 보수 비용을 추가합니다.

즉, 너무 편집증이 될 수없는 특정 지점이 있습니다. 버퍼 오버플로, 데이터 손상 및 유사한 문제의 가능성은 매우 엄격하게 방어되어야합니다.

최근에 사용자 입력 데이터가 원격 Facade 인터페이스를 통해 전파 된 다음 로컬 페이드 인터페이스, 그 다음 다른 클래스를 통해 전파 된 시나리오를 가지고 있었으며 실제로 실제로 사용되는 방법에 도달했습니다. 나는 내 스스로에게 질문을하고 있었다 : 값 검증은 언제 여야합니까? 값이 실제로 사용 된 최종 클래스에만 유효성 검사 코드를 추가했습니다. 전파 경로에 놓인 클래스에 다른 검증 코드 스 니펫을 추가하는 것은 너무 방어적인 프로그래밍입니다. 한 가지 예외는 원격 외관 일 수 있지만 나도 건너 뛰었습니다.

좋은 질문, 나는 정신 점검을하는 것과 그 일을하지 않는 사이에 뒤집 혔습니다. 50/50

상황, 나는 아마도 내가 일상적인 일상을 "방탄"만 할 수있는 중간 지점을 취할 것입니다.

(a) 프로젝트의 한 곳 이상에서 전화

(b) 변화 할 가능성이있는 논리가 있습니다.

(c) 기본값을 사용할 수 없습니다

(d) 루틴은 우아하게 '실패'될 수 없습니다.

다크 나이트

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top