複雑なソフトウェアはどの程度の冗長性/堅牢性を実装する必要がありますか?


12

この質問の焦点:一部のソフトウェアは「余分な作業」を実行して、ソフトウェア内の1つまたは複数の内部エラーにもかかわらず「最終的に成功/満足」の結果を得る機会を増やします。結果が成功した場合、これらはすべてユーザーの知らないうちに発生します。

複雑なソフトウェアの定義:

  • 存続期間中に10人以上の開発者によって作成(提供)されたコードが含まれており、同じ時間枠で記述されていない
  • それぞれに注意事項がある10以上の外部ライブラリに依存
  • 典型的なソフトウェアタスク(ユーザーが望む結果を生成するため)には10個以上の入力パラメーターが必要です。それらのほとんどはデフォルト値を持ちますが、ユーザーが制御を必要とする場合は構成可能です。
  • 最も重要なことは、実行されるタスクに関連して適切な複雑さを持つソフトウェア、つまり不必要に複雑にならないソフトウェアです。

編集:複雑なものは何ですか?ComplexとComplicatedには大きな違いがあります。をご覧ください。(直接リンク)

この質問内の冗長性/堅牢性の定義:(
コメントに基づいて堅牢性を追加)

  • 現在のパラメーターセットを使用したときにソフトウェアタスクが失敗した場合は、別のパラメーターを試してください。
    • 明らかに、これらの「異なる」パラメータは異なるコードパスを使用し、結果として異なる(できればより良い)結果をもたらす可能性があるという内部知識が必要です。
    • これらの異なるコードパスは、外部ライブラリの観察に基づいて選択される場合があります。
  • 最後に、実行される実際のタスクがユーザーの仕様とわずかに異なる場合、ユーザーは不一致の詳細を示すレポートを受け取ります。
  • 最後に、10以上の構成可能なパラメーターと同様に、冗長性とレポートも構成可能です。

そのようなソフトウェアの例:

  • データベース移行
    • ビジネスデータベース
    • ソース管理データベースなど
  • Word文書とOpenOffice文書、PowerPointおよびOpenOffice Drawなどの間のバッチ変換
  • ウェブサイト全体の自動翻訳
  • Doxygenなどのソフトウェアパッケージの自動分析。ただし、分析をより信頼性の高いものにする必要がある場合(つまり、単なるドキュメンテーションツールではない)
  • パケットが失われる可能性があり、多くの再試行が予想されるネットワーク通信

この質問はもともと、意図的に悪いコードにどのように対処しますか?
しかし、現在はソフトウェアの肥大化の原因の1つに焦点を当てています。この質問は、新機能の追加など、ソフトウェアの膨張のその他の原因には対応していません。

おそらく関連する:


5
それは冗長性ではなく、堅牢性です

5
答えは、単に「必要なだけ」ではありませんか?
ディーンハーディング

@ディーン-絶対に、それは他のような要件です。秘Theはそれを説明し、ユーザーに結果とコストを説明することですが、それは可能です。
ジョンホプキンス

フィードバックをありがとう@Thorbjørn。タイトルと定義に堅牢性を追加しました。
-rwong

5人の子供を養わない限り、古いコードベースには近づかないでください。
ジョブ

回答:


7

これは技術的な問題ではなく、ビジネス上の問題です。

時々、研究者やプロトタイプを使ってコーディングしているので、非常に堅牢性の低いものを作成します。破損した場合は修正します。コードをすぐに破棄する場合、余分な魔法に投資する意味はありません。

しかし、システムのユーザーが堅牢にする必要がある場合は、そのように構築する必要があります。そして、あなたと彼らが長期的な成功を最大化するために必要な方法で特に堅牢にする必要がありますが、彼らは必要としない種類の冗長性/堅牢性を無視します。

一般的に、私はラフに始めてから、時間とともに堅牢性を追加します。通常の計画プロセスのこの部分のような質問を頻繁に行います。私は通常、Extreme Programmingスタイルで作業します。このスタイルでは、必要な機能の長いリストを作成し、そこにも堅牢性機能を配置します。たとえば、「システムは単一のボックスの障害に耐えることができます」と「ユーザーはFacebookの資格情報を使用して参加できます」などと混同されます。どちらが先に来ても、最初にビルドします。


5

複雑なソフトウェアは、一般的であることがそれを行うための最善の方法だからしかし、開発者は既存のコードではなく、どのようにソフトウェアの動作非常に詳細に理解するための試み「にタック」する傾向があるので、あなたはおそらく知っているように冗長が、明らかではありません。

ただし、どの程度の冗長性を許容する必要があるかを尋ねられた場合、何も言わないでしょう。冗長性は、複雑さの多くの副作用の1つであり、単純さの大敵です。時間の重要性が高い場合は、おそらく単純さを後回しにする必要がありますが、時間が重要であると主張する人は、ソフトウェアの開発に実際に注意を払う人はめったにいないと強調します。通常は、プロジェクトマネージャーができるだけ早く仕事を終わらせて、より緊急の問題に戻ることができるようにしますが、仕事がいつ終わるかを知ることはプログラマーとしての義務です。本来の意図通りにプログラムにうまく統合するまで、この仕事は終わっていないと思います。おそらくプログラムは複雑で、

しかし、そうすることで、冗長なコードを生成する必要があるかもしれないと言われるべきです。プロジェクトがすでに非常に冗長な場合、もちろん上司が数週間でプロジェクト全体を再構築できるようにするために殺すための数週間がないと仮定すると、実際にパターンを継続する方が簡単かもしれません。

編集:質問の言い換えに照らして、堅牢性について少し追加します。私の意見では、パラメーターのチェックは、A)文字列としての日付値などの非常に具体的な形式を受け入れる場合、またはB)互いに矛盾する可能性のあるさまざまなパラメーターまたは相互に排他的な場合にのみ行う必要があります。

A)では、パラメータが特定の形式に一致するという要件は、通常、メソッドの必要性(文字列から日付への変換など)にとって重要です。技術的にはそれは必要ではなくプログラムで発生する可能性がありますが、これらの可能性を排除し、探しているデータのタイプを表すことがわかっているパラメータのみを受け入れることを強くお勧めします(ポイントは、たとえば、変換することではありません。変換も行う必要がある場合は、ユーティリティメソッドを使用して文字列を変換してから、メソッドに渡します。

B)に関しては、相互に排他的なパラメーターは悪い構造を表しています。2つのクラスが必要です。1つは1つのケースを処理し、もう1つは別の方法で処理します。冗長性を回避するために、すべての一般的な操作を単一の基本クラスで実行できます。

メソッドへのパラメーターの数が10以上になる状況では、頻繁に変更される可能性が最も低いこれらすべてのパラメーターを含むプロパティファイルを検討し始めます。変更する場合は、プロパティファイルにデフォルトを保存し、実行時にデフォルトをオーバーライドできる「setPropertyName()」メソッドを追加できます。


4
あなたは質問を誤解していると思います。彼は「重複コードの作成」ではなく「エラーが発生しても炎で死なない」という「冗長性」を意味します。他の人が指摘しているように、堅牢性はより良い用語です。
アダムリア

冗長性は、重要なタスクにおいてポジティブなことです。ここでは、人体が完璧な例です。
クラウディウクレアンガ

3

ソフトウェアは、ユーザーのミスを許容し、プログラマーのミスを完全に許容しないものでなければなりません。

つまり、ソフトウェアは非常に堅牢であり、ユーザー入力エラーやシステム構成エラーなどをスムーズに回復できる必要があります。少なくとも、エラーが発生した場所(入力ボックス、設定ファイル、コマンドライン引数など)と違反した制約(「X文字未満でなければならない」、「有効なオプションは[X 、Y、Z] "など)堅牢性を高めるために、ソフトウェアは代替案を提案するか、妥当なデフォルトを使用できます(ただし、ユーザーが指定したとおりに使用していないことを常に示す必要があります)。

異なるデフォルトでの自動再試行が保証される状況はあまり考えられませんが、いくつかあります(通信リンクを確立するための自動再試行は妥当と思われます)。@Williamには、このレベルの「冗長性」がビジネス上の決定であることに同意します。

一方、プログラマーのエラーに対する実行時の堅牢性はありません。関数のパラメーターに前提条件がある場合は、ランタイムチェックではなく、アサートでチェックする必要があります。コールスタックへの同じパラメーターの3つまたは4つのレベルでの冗長なエラーチェックとレポートを見るのは、私の最大の苦労です。

 int A(int x)
 {
   if (x==0) return -1
   ...
 }
 int B(int x)
 {
   if (x==0) return -1
   err = A(x)
   if (err) return err;
   ...
 }
 // and so on and so on....

これは、単なる不必要な複雑さです。ある関数が別の関数を誤用することで発生したエラーをどのように処理するかを判断するタイミングを費やすべきではありません。これがあなたが言及している「ロバストネス」のタイプであるなら、あなたはそれを必要としません。それをアサートと完全な統合テストに置き換えます。


3

これは要件です。

堅牢性の要件はありますか?

「通信リンクに障害が発生すると、誤ったパケットは破棄されます」「リンクが動作を再開すると、トランザクションは2回処理されません」

エラーリカバリのユースケースがあるはずです(それ以外の場合、どのように発生するかをどのように知るのですか?)

必要に応じて堅牢性を発明するためにプログラマに任せると、「魔法の」システムになります。

すべての魔法のシ​​ステムは、時間の経過とともにくだらない魔法になります。バックグラウンドでエラーを修正すると、障害の発生が隠されるため、障害は修正されず、システムは最終的にエントロピーの大きい状態に低下します。常にエラーを修正するので、がらくたのように実行します。システムが永続的に劣化した状態になるのを停止するには、制限が必要です。


2

特にデータベースなどの外部リソースに依存している場合、一部の操作はおそらく「再試行」アプローチを保証します。たとえば、データベースに接続できない場合やクエリが失敗した場合、操作を一定回数再試行してから、あきらめて上位レベルにエラーをスローします。ただし、一部のロジックでは、同じことを複数回試みることは、実際の問題を隠す悪いコードと魔法の思考の症状であることがよくあります。


カウントおよび報告/表示されずに再試行が行われると、システムの性能が低下し、魔法のような自己修正の性質により動作が悪くなります。再試行とエラーを報告するには、常に漏出バケットカウンター(PLOPD4)を使用します。これにより、低レベルは無視されますが、問題はユーザーに見えるようになります。
ティムウィリスクロフト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.