당신이 받아들이는 것에 자유를 주거나…


45

[면책 조항 :이 질문은 주관적이지만 사실 및 / 또는 반영으로 답변을받는 것이 좋습니다.]

나는 모든 사람들이 견고성 원칙 에 대해 알고 있다고 생각합니다 . 일반적으로 Postel의 법칙에 의해 요약됩니다.

당신이 보내는 것을 보수적으로하십시오. 당신이 받아들이는 것에 자유를 주라.

나는 광범위한 통신 프로토콜의 디자인에 대해 (쉬운 확장을 허용한다는 목표로) 의미가 있지만, 항상 HTML / CSS에 대한 응용 프로그램이 완전히 실패했다고 생각했습니다. 감지 / 동작으로 인해 여러 브라우저에서 일관된 렌더링을 얻는 것이 거의 불가능합니다.

TCP 프로토콜의 RFC가 달리 명시되지 않는 한 "무음 실패"로 간주되는 것을 알 수 있습니다.

소프트웨어 교역 전반에 걸쳐이 원칙을 적용한 다른 예가 있습니다. 개발자가 내 머리에서 맨 처음부터 물 렸기 때문에 정기적으로 나타납니다.

  • 자바 스크립트 세미콜론 삽입
  • C (자동) 기본 제공 변환 (잘라지지 않으면 그렇게 나쁘지 않을 것입니다 ...)

"스마트 한"동작을 구현하는 데 도움이되는 도구가 있습니다.

그러나이 접근법은 기술이 아닌 사용자를 처리하거나 오류 복구 프로세스의 사용자를 도울 때 도움이 될 수 있지만 라이브러리 / 클래스 인터페이스 디자인에 적용될 때 몇 가지 단점이 있음을 발견했습니다.

  • 알고리즘이 "올바른"것인지 추측하는 것은 다소 주관적이므로 최소 놀랍게도원칙에 위배 될 수 있습니다.
  • 구현이 더 어려워서 버그가 발생할 가능성이 더 높습니다 ( YAGNI 위반 )?
  • "추측"루틴을 수정하면 이전의 리팩토링 가능성을 거의 제외하고 오래된 프로그램을 중단 할 수 있기 때문에 동작을 변경하기가 더 쉽습니다.

그리고 이것이 나를 다음 질문으로 이끌었습니다.

인터페이스 (라이브러리, 클래스, 메시지)를 설계 할 때 견고성 원칙에 의존합니까?

내 인터페이스에서 광범위한 입력 유효성 검사를 사용하여 나 자신이 매우 엄격한 경향이 있으며 너무 엄격한 지 궁금합니다.


HTML과 일반 데이터의 차이점이 무엇인지 궁금합니다. 견고성 원칙은 커뮤니케이션에 관한 것입니다. 하나는 씁니다-하나는 읽습니다. 네트워크 통신이 시각적 또는 API와 다른 이유는 무엇입니까? 나는 우리가 받아들이는 것에 자유주의라는 원칙 이 프로그래머사용자 의 삶을 단순화 하고 코드 크기를 줄이므로 성능을 향상시키고 버그를 제거 하는 API 예제를 가지고 있습니다 . 룩 stackoverflow.com/questions/18576849

@Val : 실제로는 예제가 일치하지 않습니다. "당신이 받아들이는 것에 자유 주의적"이라는 것은 단지 기본 / 파생의 문제가 아니라, 그것을 넘어서고 약간 잘못된 입력을 받아들이고 해석하는 것입니다.
Matthieu M.

일부 사례를 표시하면 해당 사례가 어떻게 표시되지 않습니까?
Val

답변:


34

나는 애매함을 유발하지 않을 때 견고성 을 말할 것이다 .

예 : 쉼표로 구분 된 목록을 구문 분석 할 때 쉼표 앞 / 뒤에 공백이 있는지 여부에 따라 의미 의미가 변경되지 않습니다.

스트링 guid를 파싱 할 때, 여러 가지 일반적인 형식 (대시를 포함하거나 포함하지 않고, 중괄호를 포함하거나 포함하지 않음)을 수용해야합니다.

대부분의 프로그래밍 언어는 공백 사용으로 강력합니다. 특히 코드의 의미에 영향을 미치지 않는 모든 곳에서. 공백이 관련된 Python에서도 목록 또는 사전 선언 내부에있을 때 여전히 유연합니다.

나는 무언가가 여러 가지 방법으로 해석 될 수 있거나 의미가 100 % 명확하지 않다면 너무 많은 견고성이 고통 스러울 수 있지만 모호하지 않고 견고 함의 여지가 많이 있음에 분명히 동의합니다.


1
비용이 많이 들지 않을 때 견고성이 가치가 있다는 데 동의합니다.
Matthieu M.

2
쉼표로 구분 된 목록조차도 문제를 일으 킵니다. 크롬과 파이어 폭스의 자바 스크립트 엔진은 {"key": "value",}유효한 것으로 보이며 IE는 그렇지 않습니다. JSlint로 빌드 프로세스를 개선 할 때까지 종종이 특정 문제에 부딪 쳤습니다.
keppla

2
디자인보다는 구현에 문제가있는 @keppla. Javascript 사양에 따라 합법적이며 IE가 따르지 않는지 또는 FF와 Chrome이 추가 한 "좋은 기능"인지 확실하지 않지만 Python에서는 유효하고 구현되도록 지정되어 있습니다. 유효한 것으로 지정 되어도 작동하지 않으면 잘못된 구현입니다. 지정되지 않은 경우 실제로 의존해서는 안됩니다 (실제적으로 주요 브라우저에서 작동하지 않는 경우 사용자를 제어하지 않으면 사양에 포함되지 않은 것으로 간주 될 수 있음)
Davy8

7
@ Davy8 : 후행 쉼표가 불법 인 것 같습니다 ( stackoverflow.com/questions/5139205/… ). 나는 이것에 의존하고 싶지 않다. 내 요점은 충분한 사람들이 입력을 받아들이면 사실상 표준이된다 (왜냐하면 그것이 오류라는 것을 알지 못하기 때문이다). 더 이상 잘못된 입력으로 무시할 수 없을 정도로 평범 해집니다.
keppla

1
@keppla, moz와 Chrome에서 실패해야합니다. 주로 JS 개발자로서, 그것이 아닙니다 (최소한 Moz에서는 익숙하지 않음). 디버그가 더 어렵고 쉽지 않습니다. IE는해야 할 일을하고 있습니다. 잘못된 코드에서 실패했습니다. HTML은 한 가지입니다. 스크립팅 언어로 된이 쓰레기는 필요하지 않습니다. 이는 브라우저 공급 업체가 능가하는 강력한 원칙을 끔찍하게 적용한 예입니다.
Erik Reppen

15

기필코 아니다. 방어 적 프로그래밍과 같은 기술은 버그를 가려서 모양이 불규칙하고 무작위성이 낮아 탐지가 더욱 어려워서 분리하기가 더 어려워집니다.

매우 저평가 된 Writing Solid Code 는 버그를 도입하거나 숨기는 것을 어렵게 만드는 필요성과 기술을 반복적으로 강조하는 데 엄청났습니다. "임의의 행동을 제거하고 버그를 재현 할 수있게하십시오"와 같은 원칙을 적용 함. "항상 인터페이스의 결함을 찾아 제거합니다." 개발자는 대량의 버그를 유발하는 모호함과 통제되지 않은 부작용을 제거하여 소프트웨어의 품질을 크게 향상시킬 것입니다.


9

견고성을 과도하게 적용하면 사용자가 원하는 것을 추측 할 수 있습니다. 또한 고객이 신뢰를 남용하지 않고 작동하는 임의의 횡설수설을 만들지 만 버전 2에서는 지원할 수 없다는 완전히 잘못된 믿음이 필요합니다.

정확성을 과도하게 적용하면 고객이 사소한 오류를 범할 수있는 권리를 거부하게되는데, 이는 경쟁 업체의 제품에서 문제가 잘 작동한다고 불만을 표시하고 5,000 페이지 표준으로 할 수있는 일을 알려줄 때까지는 괜찮습니다. "DRAFT"는 여전히 크레용으로 뒤덮여 있으며, 적어도 3 명의 전문가 주장에 근본적인 결함이 있으며, 200 명의 정직한 전문가가 완전히 이해하지 못한다고 말합니다.

내 개인 솔루션은 항상 지원이 중단되었습니다. 당신은 그들을 지원하지만, 그들이 잘못하고 있다고 말하고 (가능한 경우) 가장 정확한 길을 간다. 이런 식으로 버그 기능을 10 년 동안 줄이려고 할 때 최소한 "우리는 이것이 일어날 수 있음을 경고했다"는 문서를 가지고 있습니다.


더 이상 사용되지 않는 +1 , 그것은 실제로 중요한 개념이며 지금까지 간과되었다는 것에 놀랐습니다.
Matthieu M.

9

불행히도 소위 "견고성 원칙"은 견고성을 이끌어 내지 않습니다. HTML을 예로 들어 보자. 브라우저가 조작 된 컨텐츠의 의미를 추측하는 대신 HTML을 엄격하게 구문 분석 한 경우 많은 문제점, 눈물, 시간 낭비 및 에너지를 피할 수있었습니다.

브라우저는 표지 아래에 오류를 수정하는 대신 오류 메시지를 표시했을뿐입니다. 그것은 모든 벙어리가 그들의 혼란을 고치도록 강요했을 것입니다.


나 자신을 인용 (늙어 야 함) : "하지만 항상 HTML / CSS에 대한 응용 프로그램이 완전히 실패했다고 생각했습니다"
Matthieu M.

3
사실, 동일한 내결함성으로 인해 웹이 인기를 끌었습니다.
MaR

브라우저 공급 업체는 그 중 하나에서 실패했습니다. doctype을 사용하면 우리는 이와 관련하여 우리 자신의 선택을 할 수 있었지만, 하루가 끝날 때 모든 doctype이 선언 된 한 거의 모든 방식이 동일하게 작동했습니다. 이제 그들은 실패를 처리하는 방법과 관련하여 따라야 할 복잡한 규칙의 복잡한 규칙이 해결책이라고 생각합니까? 나는 그들이 문제를 식별하지 못한다고 생각합니다.
Erik Reppen

당신은 "견고한"의 반대 인 페일 패스트가 더 효율적이라고 말합니다.
Val

@MaR : 그래요? 매우 논쟁의 여지가 많았으며 기능이 훨씬 중요했습니다.
중복 제거기

6

인터페이스를 여러 그룹으로 나눕니다 (원하는 경우 더 추가).

  1. 통제하에있는 것들은 엄격해야합니다 (일반적으로 수업)
  2. 라이브러리 API도 엄격해야하지만 추가 검증이 권장됩니다.
  3. 들어오는 모든 종류의 남용을 처리해야하는 공용 인터페이스 (일반적으로 프로토콜, 사용자 입력 등) 여기에 입력에 대한 견고성이 실제로 도움이됩니다. 모든 사람이 물건을 고칠 것이라고 기대할 수는 없습니다. 그리고 응용 프로그램이 작동하지 않으면 잘못된 형식의 쓰레기를 보낸 당사자가 아닌 사용자의 잘못이라고 생각하십시오.

출력은 항상 엄격해야합니다.


5

HTML과 월드 와이드 웹 (World Wide Web)은 견고성 원칙에 대한 광범위한 실제 테스트를 제공했으며 이것이 큰 실패임을 보여 주었다. 웹 개발자 (및 사용자)에게 인생을 비참하게 만들고 새로운 Internet Explorer가 출시 될 때마다 더 나빠지는 경쟁 HTML 거의 표준의 혼란스러운 혼란에 직접 책임이 있습니다.

우리는 1950 년대부터 코드를 올바르게 검증하는 방법을 알고있었습니다. 엄격한 파서를 통해 실행하고 구문 상 올바르지 않은 것이 있으면 오류를 던져 중단하십시오. 통과하지 말고 200 달러를 모으지 마십시오. 바이너리 인 모든 것을 사랑 하기 위해 실수를 한 컴퓨터 프로그램이 코더의 마음을 읽으려고하지 마십시오!

HTML과 JavaScript는 이러한 원칙을 무시할 때 어떤 일이 발생하는지 정확하게 보여줍니다. 최선의 행동은 실수로부터 배우고 반복하지 않는 것입니다.


4
@ ChaosPandion : 문제는 내가 생각하는 Internet Explorer 자체가 아니라 이전 버전에서 받아 들여졌고 모든 사람들이 함께 살아야한다는 모든 비표준 웹 페이지에 있습니다 ... 그리고 다소 성공적으로 수용하려고합니다.
Matthieu M.

5
실제로 IE 팀은 모든 브라우저 개발자에게 최악의 위치에 있다고 생각합니다. Joel은 내 생각을 꽤 멋지게 요약합니다 .
Dean Harding

3
개발자와 디자이너에게는 인생을 비참하게 만들었을지 모르지만, 우리는 매우 느리게 발전하고 정적 인 표준에 갇혀 있었을 것입니다. 진정한 승자는 웹을 탐색하는 사람들이었으며 하루가 끝날 무렵에는 사람들이 셀 수 있습니다.
FinnNk

4
또한 견고성 (Robustness) 원칙으로 인해 웹 개발자의 삶이 어려워 질 수 있지만 월드 와이드 웹 (현재는 지구상의 거의 모든 주요 기관의 필수 부분)을 대규모 실패 라고 부르기가 어렵습니다 .
deworde

3
"우리는 1950 년대부터 코드를 올바르게 검증하는 방법을 알고 있습니다. 엄격한 구문 분석기를 통해 코드를 실행하고 구문 상 정확하지 않은 경우 오류를 발생시키고 중단하십시오." 이것을 실제 시나리오에 적용하려면 : 컷 바로 아래의 페이지 맨 오른쪽에 하나의 아이콘을 조이면 전체 페이지를 포기하는 것이 다른 사람을 다른 사람에게 보내는 좋은 방법입니다. 문제조차도 눈치 채지 못했을 것입니다. 네, 내가 실수하지 말았어야한다고 주장 할 수 있습니다. 그러나 그것은 이미 당신의 더 강력한 경쟁자에게 가지 않고 더 이상 당신의 전화를받지 않을 것을 전제로합니다.
deworde

3

Mason의 사례에 대한 반격으로, Session Initiation Protocol 에 대한 저의 경험 은 다른 스택이 관련 RFC를 다르게 해석하지만 (이것은 모든 표준에서 발생 한다고 생각합니다.) 실제로 두 장치간에 전화를 걸 수 있습니다. 이러한 장치는 데스크톱의 소프트웨어와 달리 일반적인 물리적 인 요소이므로 수락 한 내용에 대해 자유로 워야합니다. 그렇지 않으면 휴대폰에서 특정 제조업체의 다른 휴대폰으로 전화를 걸 수 없습니다. 그것은 당신의 전화를 좋아 보이지 않습니다!

그러나 라이브러리를 작성하는 경우 여러 당사자가 공통 표준을 상호 호환되지 않는 방식으로 해석하는 데 문제가 없을 수 있습니다. 이 경우 모호성을 제거하기 때문에 귀하가 받아들이는 것에 엄격하다고 말하고 싶습니다.

전문 용어 파일 에는 사용자의 의도를 "추측"하는 공포 이야기 가 있습니다.


난 당신이 기존 시스템과 상호 작용 할 때 작동하지 않는 경우 때문에 당신이 더 여유가 필요할 수 있습니다 것을 깨닫게 아주 재미있는 이야기 : 당신은 '비난 할 것이다.
Matthieu M.

실제로 휴대 전화가 대부분의 다른 휴대 전화와 작동하지 않으면 휴대 전화가 나쁘다는 것 입니다.
SamB

1
@SamB : badbroken으로 교체하십시오 .
deworde

3

규칙이 프로토콜이 아닌 프로그래밍에 적용됩니다. 프로그래밍하는 동안 오타를 작성하면 컴파일하자마자 오류가 발생합니다 (또는 동적 유형 중 하나 인 경우 실행). 컴퓨터가 당신을 추측하게함으로써 얻을 수있는 것은 없습니다. 일반적인 사람들과 달리 우리는 엔지니어이며 정확히 무엇을 의미하는지 말할 수 있습니다. ;)

따라서 API를 디자인 할 때 견고성 원칙을 따르지 않는다고 말할 있습니다. 개발자가 실수하면 즉시 그 사실을 찾아야합니다. 물론 API가 파일과 같은 외부 소스의 데이터를 사용하는 경우에는 관대해야합니다. 라이브러리 사용자는 자신의 실수에 대해 알아 내야하지만 다른 사람의 실수는 찾아서는 안됩니다.

따로, TCP 프로토콜에서 "자동 실패"가 허용되는 것 같습니다. 그렇지 않으면 사람들이 잘못된 패킷을 던지면 오류 메시지가 표시 될 수 있습니다. 바로 간단한 DoS 보호입니다.


1
"프로그래밍하는 동안 오타를 작성하면 컴파일하자마자 오류가 발생합니다."수백만 개의 컴파일러를 제공합니다. 경고 표준 컴파일러는 그대로 실행하면서도 완벽하게 실행 가능한 작업을 생성합니다.
deworde

1

IMO의 견고성은 "바람직한"원칙이 아닌 설계 절충의 한 측면입니다. 많은 사람들이 지적했듯이 4 시간 동안 JS가 잘못되었다는 것을 파악하려고 시도하는 것만으로 실제 문제를 발견하기 위해 한 브라우저만이 XHTML Strict로 올바른 일을했다는 것입니다. 제공된 HTML의 일부가 완전한 재앙이되었을 때 페이지가 조각으로 나아갔습니다.

다른 한편으로, 누가 20 개의 인수를 취하는 방법에 대한 문서를 찾고 싶어하고 건너 뛰고 자하는 값이 비어 있거나 널인 자리 표시 자와 정확히 같은 순서로 주장하고 있습니까? 이 방법을 처리하는 끔찍한 강력한 방법은 모든 인수를 확인하고 상대 위치 및 유형을 기반으로 한 것이 무엇인지 추측 한 다음 조용히 실패하거나 의미없는 인수로 "만들기"를 시도하는 것입니다.

또는 객체 리터럴 / 사전 / 키-값 쌍 목록을 전달하여 프로세스에 유연성을 부여하고 각 인수의 존재를 처리 할 수 ​​있습니다. 아주 작은 perf tradeoff의 경우, 그것은 케이크이며 시나리오도 먹습니다.

지능적이고 인터페이스에 일관된 방식으로 인수를 오버로드하는 것은 사물을 강력하게하는 현명한 방법입니다. 따라서 중복성을 기존의 광범위한 전송 수단을 갖춘 새로운 기술 분야의 모든 사람이 소유하고 운영하는 대규모 복잡한 네트워크에서 정기적으로 전달하지 못하는 것으로 가정되는 시스템으로 중복성을 베이킹하고 있습니다.

그러나, 특히 사용자가 제어하는 ​​시스템 내에서 절제 실패를 허용하는 것은 결코 좋은 절충안이 아닙니다. 예를 들어 JS를 페이지의 맨 위 또는 맨 아래에 배치하는 것에 대한 또 다른 질문에 히스를 맞추지 않기 위해 숨을 쉬어야했습니다. 여러 사람들이 JS를 맨 위에 놓는 것이 더 좋다고 주장했습니다. 페이지가 완전히로드되지 않으면 여전히 일부 기능이 있기 때문입니다. 반 작업 페이지는 전체 버스트보다 나쁩니다. 기껏해야 사용자가 확인 페이지에 실패한 후 오류가 발생한 페이지가 단순히 오류 페이지로 튀어 나와서 자동으로 전자 메일을 보내는 경우보다 사이트를 발견하기 전에 귀하가 무능하다고 가정하여 사이트 방문자가 많아 질 수 있습니다. 그것에 대해 뭔가 할 수있는 사람.

낮은 기술 페이지 만 제공 할 수있을 때 1999 브라우저에서 2010 기능을 제공하는 것은 바보 같은 디자인 트레이드 오프의 또 다른 예입니다. 내가 본 기회와 돈은 버그를 타는 해결 방법에 소비 된 개발자 시간에 낭비되었습니다. 예를 들어! @ # $ ing 그라디언트 배경 위에 떠오르는 요소의 모서리를 구하기 위해 완전히 날아갔습니다. 그리고 무엇을 위해? 검증 된 테크노 포브에게는 성능이 떨어지는 첨단 기술 페이지를 제공하는 동시에 고급 브라우저에서 선택을 제한합니다.

올바른 선택이 되려면 입력을 강력한 방식으로 처리하도록 선택하면 단기 및 장기 IMO에서 문제의 양쪽 측면에서 항상 생활이 더 쉬워집니다.


4
> 필요가 없습니다 "(20 개) 인수를 취하는 방법에 대해"더보고, 5/6 후 방법은 잘못 . 그래도 답변 주셔서 감사합니다 :)
Matthieu M.

1

조용히 실패하지 마십시오 . 그 외에도 API / 라이브러리 사용자가 원하는 것을 추측하려고 시도하는 것은 나쁜 생각처럼 들리지 않습니다. 나는 그것을 따르지 않을 것이다. 엄격한 요구 사항이 있으면 호출 코드의 버그 및 / 또는 API / 라이브러리에 대한 잘못된 해석이 노출 될 수 있습니다.

또한 이미 지적했듯이 실제로 사용자가 무엇을 기대했는지 추측하기가 얼마나 어려운지에 달려 있습니다. 매우 쉬운 경우 두 가지 경우가 있습니다.

  1. 사용자가 실제로 제공하는 것을 기대할 수 있도록 라이브러리를 약간 다르게 디자인해야합니다 (일부 기능의 이름을 바꾸거나 두 개로 나눕니다).
  2. 라이브러리가 올바르게 / 명확한 이름 지정을 의미하여 올바르게 설계되었다고 생각되면 사용자가 의도 한 것을 추론 할 수 있습니다.

100 % 명확하고 결정적이지 않은 경우, 하나의 입력을 다른 입력으로 변환해야하는 경우, 이미 언급 한 여러 가지 이유로 리팩토링 호환성을 깨뜨리고 사용자를 놀라게하는 등의 이유로 변환을 수행해서는 안됩니다.

최종 사용자를 다룰 때 입력 / 추측을 고치려고 시도하는 것은 매우 환영합니다. 그는되는 것으로 잘못된 정보를 입력; 이 경우는 완전히 예외가 아닙니다. 그러나 다른 개발자는 단순한 기술이 아닌 사용자가 아닙니다. 그는 오류를 이해하는 데 전문 지식이 있으며 오류는 그에게 의미가 있거나 유익 할 수 있습니다. 따라서 엄격한 API 디자인에 대해서는 동의하지만 물론 엄격에는 명확성과 단순성이 수반됩니다.

비슷한 경우에 대한 내 질문 을 읽는 것이 좋습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.