質問

免責事項:この質問は主観的ですが、事実や反射に裏付けられた答えを得ることを好むでしょう

誰もが知っていると思います 堅牢性の原理, 、通常、Postelの法律によって要約されています。

あなたが送るものに保守的である。あなたが受け入れるものでリベラルになりなさい。

広範囲にわたる通信プロトコルの設計のためにこれは理にかなっている可能性があることに同意します(簡単な拡張を許可することを目標としていますが)が、HTML / CSSへのアプリケーションは完全な障害であり、各ブラウザが独自のサイレントツーークを実装していると常に考えてきました。検出 /動作により、複数のブラウザで一貫したレンダリングを取得することはほぼ不可能になります。

ただし、TCPプロトコルのRFCは、特に指定されていない限り「サイレント失敗」を受け入れられるとみなしていることに気付きます...控えめに言っても、これは興味深い動作です。

ソフトウェアトレード全体を通してこの原則を適用する他の例があります。これは、私の頭の上からの開発者が噛んだために定期的にポップアップします。

  • JavaScriptセミコロン挿入
  • c(サイレント)ビルトイン変換(切り捨てられなかった場合、それほど悪くはない...)

そして、「スマート」な動作の実装を支援するツールがあります。

ただし、このアプローチは、非技術的なユーザーを扱うときに役立つかもしれませんが、エラー回復の過程でユーザーを支援する場合は、ライブラリ/クラスのインターフェイスの設計に適用されると、いくつかの欠点があります。

  • アルゴリズムが「正しい」と推測しているかどうか、したがって、それが反対する可能性があるかどうかはやや主観的です 最も驚きの原則
  • 実装がより困難になるため、バグを導入する可能性が高くなります(の違反 ヤグニ ?)
  • 「推測」ルーチンの変更は古いプログラムを破る可能性があり、最初からリファクタリングの可能性をほぼ除外する可能性があるため、動作は変化の影響を受けやすくなります!

そして、これが私を次の質問に導いたものです。

インターフェイス(ライブラリ、クラス、メッセージ)を設計するとき、あなたは堅牢性の原則に傾いていますか?

私自身は、自分のインターフェイスで広範な入力検証を使用して、非常に厳格である傾向があり、おそらく私があまりにも厳格であるかどうか疑問に思っていました。

役に立ちましたか?

解決

私は言うでしょう あいまいさを導入しないときの堅牢性.

例:コンマ分離リストを解析する場合、コンマの前後にスペースがあるかどうかは、セマンティックの意味が変わりません。

文字列のガイドを解析する場合は、一般的な形式の数を受け入れる必要があります(巻き毛の装具の有無にかかわらず、ダッシュの有無にかかわらず)。

ほとんどのプログラミング言語は、空白の使用で堅牢です。具体的には、コードの意味に影響しないすべての場所。 Whitespaceが関連するPythonでも、リストや辞書宣言の中にいる場合でも柔軟です。

何かが複数の方法を解釈できる場合、またはそれが何を意味するのか100%明確でない場合、あまりにも堅牢性が痛みになる可能性があることに間違いなく同意します。

他のヒント

絶対にありません。防御プログラミングなどの手法 あいまいな バグは、見た目が少なく、ランダムになり、検出が難しくなり、分離がより困難になります。

非常に過小評価されています ソリッドコードを書く バグを導入または隠すのが難しいと際立つようにする必要性とテクニックを繰り返し強調することに途方もないものでした。 「ランダムな動作を排除する。力のバグが再現可能である」などの原則を適用することにより。そして、「常にあなたのインターフェイスに欠陥を探し、排除します。」開発者は、大量のバグの原因となる曖昧さと制御されていない副作用を排除することにより、ソフトウェアの品質を大幅に向上させます。

堅牢性の過剰適用は、ユーザーが望んでいたものを推測することにつながります。これは間違っているまで問題ありません。また、顧客があなたの信頼を悪用したり、たまたま機能しているランダムなギブリッシュを作成したりしないという完全に見当違いの信仰が必要ですが、バージョン2でサポートできないことです。

正確性の過剰適用は、顧客が軽微なエラーを犯す権利を否定することにつながります。これは、競合他社の製品で自分のものが正常に機能することを不平を言うまで問題ありません。 「ドラフト」はまだクレヨンの表紙に走り回っており、少なくとも3人の専門家の主張には根本的に欠陥があり、200人の正直な専門家は完全に理解していないと言います。

私の個人的な解決策は常に非難でした。あなたは彼らをサポートしますが、彼らが間違っていることを彼らに伝え、(可能であれば)正確性への最も簡単な道を。そうすれば、バグの食事を10年後にオフにすると、少なくとも「これが起こるかもしれないと警告した」と述べるために紙の道があります。

残念ながら、いわゆる「堅牢性の原理」は堅牢性につながりません。例としてHTMLを取ります。ブラウザが不正なコンテンツの意味を推測しようとするのではなく、最初からHTMLを厳密に解析した場合、多くのトラブル、涙、時間とエネルギーの無駄を避けることができたでしょう。

ブラウザは、カバーの下で修正しようとする代わりに、単にエラーメッセージを表示する必要があります。それはすべてのバングラーが彼らの混乱を修正することを強いたでしょう。

インターフェイスをいくつかのグループに分けます(必要に応じて追加します):

  1. あなたの管理下にあるものは厳格でなければなりません(通常、クラス)
  2. ライブラリAPI、それは厳格な側にあるはずですが、追加の検証はアドバイスされています
  3. 入っているあらゆる種類の乱用(通常はプロトコル、ユーザー入力など)を処理する必要があるパブリックインターフェイス。ここで、入力に対する堅牢性は本当に報われます。誰もが自分のものを修正することを期待することはできません。そして、ユーザーにとっては、アプリケーションが機能しない場合、不正なパーマットのがらくたを送った当事者ではなく、それがあなたのせいであることを忘れないでください。

出力は常に厳格でなければなりません。

HTMLとWorld Wide Webは、堅牢性の原則の広範な実世界のテストを提供し、それが大きな失敗であることを示したと思います。 Web開発者(およびそのユーザー)にとって人生を惨めにし、新しいインターネットエクスプローラーのリリースごとに悪化する競合するHTMLの混乱した混乱について直接責任を負います。

1950年代以来、コードを適切に検証する方法を知っています。厳格なパーサーを通してそれを実行し、何かが構文的に正しい場合は、エラーを投げて中止します。通過しないで、200ドルを集めないでください、そしてバイナリであるすべての愛のために 彼が間違いを犯した場合、コーダーの心を読み込もうとしないでください!

HTMLとJavaScriptは、それらの原則が無視されたときに何が起こるかを正確に示しています。最善の行動は、彼らの間違いから学び、繰り返さないことです。

メイソンの例とのカウンターポイントとして、 セッション開始プロトコル それは、異なるスタックが関連するRFCを異なる方法で解釈するだろうと思いました(そして、私はこれが起こると思います 毎日 これまでに書かれた標準)、あなたが受け入れるもので(適度に)リベラルであることは、あなたが実際に2つのデバイス間で電話をかけることができることを意味します。これらのデバイスは、デスクトップ上のソフトウェアの断片とは対照的に通常の物理的なものであるため、あなたはあなたが受け入れるものにおいて自由である必要があるか、あなたの電話が特定のメイクの別の電話に電話することはできません。それはあなたの携帯電話の見た目を良くしません!

しかし、ライブラリを書いている場合、相互に互換性のない方法で共通の基準を解釈する複数の当事者の問題はおそらくないでしょう。その場合、私はあなたが受け入れるものに厳格であると言います。なぜなら、それは曖昧さを排除するからです。

Jargonファイルにはを持っています 怖い話 ユーザーの意図を「推測」します。

あなたは正しい、ルールはプログラミングではなくプロトコルに適用されます。プログラミング中にタイプミスを行うと、コンパイルされるとすぐにエラーが発生します(または、動的なタイプの場合は実行されます)。コンピューターに推測させることで得られるものは何もありません。一般的な人々とは異なり、私たちはエンジニアであり、私が意味することを正確に言うことができます。 ;)

だから、APIを設計するとき、私は言うでしょう しないでください 堅牢性の原則に従ってください。開発者が間違いを犯した場合、すぐにそれを見つける必要があります。もちろん、APIがファイルのように外部ソースからのデータを使用している場合、あなたは寛大である必要があります。 ライブラリのユーザーは、自分の間違いについて知る必要がありますが、他の人のユーザーではありません。

余談ですが、TCPプロトコルでは「サイレント障害」が許可されていると思います。そうしないと、人々があなたに不正なパケットを投げている場合、エラーメッセージで砲撃されるからです。それはすぐに簡単なDOS保護です。

IMO、堅牢性は、「好ましい」原則ではなく、デザイントレードオフの片側です。多くの人が指摘しているように、JSがどこで間違ったのかを把握しようとして、実際の問題を発見するためだけにJSがどこでうまくいったのかを吹き飛ばそうとすることは、XHTML Strictで適切なことをしたことを発見することを悪臭を放つものはありません。提供されたHTMLの一部が完全な災害であったとき、それはページを断片にすることができました。

一方、20の引数を取り、スキップしたいものの空またはヌルの価値のある場所を使用してまったく同じ順序であると主張する方法のドキュメントを調べたい人はいますか?その方法に対処するための同様にひどい堅牢な方法は、すべてのARGをチェックし、相対的な位置とタイプに基づいて何があるかを推測し、静かに失敗するか、意味のないargで「やる」ことを試みることです。

または、オブジェクトリテラル/辞書/キー値ペアリストを渡すことにより、プロセスに柔軟性を焼くことができ、各ARGの存在を処理することができます。非常にマイナーなパフォーマンストレードオフの場合、それはケーキであり、シナリオも食べます。

インテリジェントでインターフェイス親和的な方法でのARGをオーバーロードすることは、物事について堅牢になる賢明な方法です。そのため、パケット配信が定期的に配信されると想定されるシステムに冗長性を焼くことも、伝送のためのさまざまな潜在的な手段を備えた新興技術分野のすべての人が所有し、運営する大規模なネットワークで提供されません。

ただし、特にあなたが制御するシステム内では、ab障害を許容することは、決して良いトレードオフではありません。たとえば、JSをページの上または下部に置くことについての別の質問にHissy Fitを投げないように、息抜きを取る必要がありました。何人かの人々は、ページが完全にロードできなかった場合でも、何らかの機能がある可能性があるため、JSを上に置く方が良いと主張しました。半球のページは、完全なバストよりも悪いです。せいぜい、彼らはあなたがそれについて知る前にあなたが無能であると仮定してあなたのサイトへのより多くの訪問者をもたらします。それについて何かできる人。クレジットカード情報を常に半分バストされているサイトに渡すのが快適だと思いますか?

1999年のブラウザで2010年の機能を低い技術ページを配信できるときに提供しようとすることは、愚かなデザインのトレードオフのもう1つの例です。吹き飛ばされた機会と、私が見たお金は、バグに乗った回避策に費やした時間に無駄になったお金は、!そして何のために?ハイエンドブラウザで選択を制限しながら、実証済みのテクノフォーブに対して不十分に機能するハイテクページを提供する。

それが正しい選択であるためには、堅牢な方法で入力を処理する選択は、問題の両側、略して、長期的なIMOで常に生活を楽にする必要があります。

静かに失敗しないでください. 。それとは別に、API/ライブラリのユーザーが望んでいたものを推測しようとすると、悪い考えのようには聞こえません。私はそれに従わないでしょう。厳密な要件を持つことで、呼び出しコードのバグやAPI/ライブラリに関する誤解を公開することができます。

さらに、すでに指摘されているように、それはユーザーが何を期待したかを実際に推測するのがどれほど難しいかによって異なります。非常に簡単な場合は、2つのケースがあります。

  1. ライブラリの設計を少し異なるように設計する必要があります(関数の名前を変更するか、2つに分割します)。ユーザーが実際に提供するものを期待できるようにします。
  2. ライブラリが適切に設計されていると思われる場合は、クリア /ストレートネーミングを意味する場合は、ユーザーが意図したものを推測することができます。

いずれにせよ、1つの入力を別の入力に変換する必要があることは100%明白で決定論的ではありません。すでに言及されている多くの理由(リファクタリングの互換性、ユーザーの最小限の驚き)のために、変換を行うべきではありません。

エンドユーザーを扱うとき、入力/推測を修正しようとすることは大歓迎です。彼は 期待される 無効な情報を入力するには。このケースは完全に例外的です。ただし、別の開発者は、単純な非技術ユーザーではありません。彼にはエラーを理解する専門知識があり、エラーは彼にとって重要/有益である可能性があります。したがって、私は厳格なAPIの設計に同意しますが、もちろん、厳格さには明快さとシンプルさが伴います。

読むことをお勧めします 私のこの質問, 、同様のケースの。

ライセンス: CC-BY-SA帰属
所属していません softwareengineering.stackexchange
scroll top