あなたのデザインはひどい

...しかし、それは大丈夫です。 どんなデザインでもダメです。 そして、それは常に吸うでしょう。



あなたが私を信じないなら、説明しましょう...



実装を伴う会議を生き残る単一のプロジェクトはない



自分が設計したものを実現し始めると、最初の期待に合わないものが現実に出会うことは避けられません。



外部サービスの応答で必須と予想したデータが存在しない(または無効である)場合があります。 予想される一意性は、実際には完全に一意であることが判明する場合があります(sha1で衝突が発生する場合もあります)。 信頼できると想定されていたプロセスは、予想よりもはるかに頻繁に落ちます。



これは正常です。



場合によっては、単に不明瞭にするか、例外をスローするか、何らかの方法で大声で落ちることができます。 それ以外の場合、システム要件を緩和する必要があります。 または、「クリーニング」を行い、入力データの正しいバージョンをシステムに転送する追加のフィルターレイヤーを追加します。



欠落データはオプションにするか、デフォルトで置き換えることができます。



不正なデータは欠落していると見なすか、「そのまま」記録して、検証済みバージョンを追加します。これは、元のデータが有効な場合にのみ存在します。



一意性制限が可能です キャンセルするか、データを保持するか、いずれかのバージョンを選択します。



信頼できないプロセスに再度アクセスしたり、その結果をオプションにしたり(必要に応じて次回アクセスしたり)、障害を明示的に処理したりできます。



仮定の違反を誤りと見なすか、中間層を追加するか、システムの概念を修正して現実とより一致させるかは、それぞれ個別に決定する必要があります。 それは常に公正な妥協の決定です。あなたのシステムを複雑にすることは、外の世界で面倒なことの価値がありますか?



実際のユーザーとのミーティングを生き延びるプロジェクトはありません



あなたの概念モデルはエレガントで正しいかもしれませんが、それがユーザーの心のモデルに合わない場合、あなたは不満のあるユーザーになるでしょう。 または、ユーザーがまったくいません。



人々は予期しないパラメーターで検索します(「はい、client_idで検索できることは知っていますが、どの電話から電話をかけ、検索するのがずっと簡単です」)。



人々は迷信的な習慣を身に付けます-「すべてを支払い、再構築する」などの機能が予想よりも頻繁に使用されることを期待します。



人々はあなたのシステムを決して開発されていないものに使用しますが、一見すると一見そうに見えるかもしれません-そして彼らは10メガバイトのpdf smsを送信できないと叫び、不平を言うでしょう。



データの検索などのパフォーマンスの問題に直面した場合、検索できるフィールドを制限する(おそらく苦情が急増する)か、インデックスを追加するか、データを再編成するか、外部検索エンジンを実装します。



迷信に直面した場合、不適切に使用された機能へのアクセスを制限する(再度苦情を申し立てる)か、インターフェースを変更してユーザーを本当に使用すべき機能に移動させるか、実際に状況を判断するためのトリッキーなロジックを追加するより単純なアクションで十分です。



予期しないユースケースを発見した場合、それらを間違っていると宣言するか(苦情...および、おそらく他の2種類の問題のいずれかを追加する回避策)、または当初は計画されていなかったという事実にもかかわらず、サポートを実装するか、または他と統合しますそのような機能を提供するサービス。



繰り返しますが、これらはすべて妥協です。 そして、アクションには3つの主なオプションがあることがわかります。



3つの典型的な回答



「仮定に違反した場合にエラーをスローする」および「いいえ、これはスクープではありません」-つまり、モデルに関連する問題の承認を拒否することを含むものを無視します。 このオプションは慎重に適用する必要がありますが、システムの基本原則が損なわれた場合は、真剣に検討する必要があります。



適応するには 、「リラックス制限」と「インデックスの追加」を扱います。つまり、問題のあるシナリオがうまく処理されるように設計を微調整します。 これは、「ほぼ適切」なシナリオ、つまり「何が」と「何が必要か」との差異が小さい場合に最適なデフォルトオプションです。



システムと外部の世界との間、またはシステムとユーザーの期待との間の中間層を含む外部に転送します。つまり、ユーザーが見るように、システムのコアの外部に、しかしシステム全体に何かを追加します。 このオプションは、システムの基本原則に反するよりも、システムの基本原則により直交するシナリオに最適です。



未来に会って生き残るプロジェクトはありません



上記のすべてを考慮しても、確実に言えることは2つだけです。少なくともプロジェクトの一部-最悪。 そして6か月後、あなたはこの部分が現在考えている以上のものであることに気付きます。



システムの開発中に学習します。 システムのユーザーを観察するときに学習します。 そして、システムがクラッシュし、3晩で誰かがパニックになったときを私たちは間違いなく学びます。



そして、これらすべてをどうするか? 私がこれまでに見つけた最高のアイデアは非常に単純です。すべてがうまくいかないという前提で設計し、これらの「そうではない」結果をできるだけ簡単に修正できるようにします。



実際、優れたプログラミングの基本原則はすべて、このアプローチの結果と考えることができます。



保護プログラミングは、外の世界でプロジェクトと現実の不一致が明らかになったときに、システムがエラーを報告することを意味します。つまり、エラーを修正して生き続けることができ、エラーの過少処理の結果として形成された破損したデータを修復する必要がないことを意味します(または:綿密なチェックにより、システムが適合していないすべてのものが明確に見えるようになります。



動作するだけの最も単純な構造の構築は、仮説に陥らないことを意味します。これは、将来を予測するという事実からの保護だけでなく、最低限のものも含むことを意味します。 コードが少ないほどバグが少なく、アーキテクチャ要素が少ないということは概念的なエラーが少ないことを意味します(またはYAGNIは適応の準備です)。



責任を共有するということは、外部の世界が特定の実装に依存せず、実装が失敗したことに突然気付いたときに、外部のコードを作り直すことを心配せずに、それを作り直すか置き換えることができるため、実装の詳細が外部に「漏洩」しないことを意味しますシステムのこの部分(または:区分化-これは、集約システムのフレームワーク内の主要な外部化です)。



合計



あなたのデザインはダメです。



そして、それは常に吸うでしょう。



あなたのプロジェクトが今すぐにうまくいかないようであれば、それはあなたが何かを見逃しているからです。



あなたが何かを見逃していないと確信しているなら、あなたは未来を見ることができないことを忘れています。



後で、間違いなく、絶対に正確に、必ず再設計することを前提に設計してください。



それにもかかわらず、新しいバージョンはまだずさんであることに注意してください。



そして最も重要なこと:それについてあまり心配しないでください。 「手」という音は、無能の認識ではなく、不溶性から些細な問題に変化する問題によって発生するノイズです。



個人的には、私は自分がバカだったことを認識するのが好きです。



だから、あなたのデザインが悪いことは普通です。



落ち着いてください。 少し落ち着いてください。 別の方法で解決してください。 学習を続けます。



そして、覚えておいてください-スロップをリリースすることは、何もリリースしないよりも100%優れています。



良いハッキングをしてください。



著者について:Matt Troutは、Perl開発者、Shadowcat Systems Limited(ソフトウェア開発の分野でコンサルティング)の技術専門家、ORM DBIx :: Classの著者、Catalyst Webフレームワークの主要な触媒の1つ、CPANの多くのモジュールの著者です。




All Articles