回答:
すぐに必要になるとわかっているものだけのソリューションを設計してください。2年以内に必要になる可能性のあるものを設計しないでください。非常に異なるものが必要になる可能性が高く、とにかく再設計する必要があります。
「次のリリースでこのデザインを使用して顧客の要件Zを実行できるようにする」のではなく、「将来この時点でXまたはYを実行できるようになります」と話し始めた瞬間に、建築天文学に。
コメントに応えて:
YAGNI
今日まで聞いたことがない。
反復アプローチを使用すると、この問題はほとんどなくなります。コードは最初の日とその後ほぼ毎日実行する必要があります。最初に最小要件を満たし、時間があれば追加してください。長期間コードを実行できない大きな変化を逃さないでください。
簡単なソリューションが終了してから次に自然にアップグレード/修正されるまでの潜在的な悪影響よりも、完了するまでに余分な時間がかかる場合、ソリューションは過剰になります。
基本的に、あなたは今、時間と時間を取引しています。あなたが今より多くの時間を費やしているなら、あなたは後で節約するでしょう、あなたはそれを間違っています。本当にエンジニアリングをしているのであれば、あなたは今時間を費やしていますが、それはあなたが後で費やす時間に影響を与えません(あるいはそれをもっと長くします)。
より多くの経験を積むほど、うまく機能します。(私の経験から)物事を進める最良の方法は、今必要なことをすることですが、後の要件で要求された場合に最も簡単に拡張できる方法で行います。それを行う方法を理解するのは難しいことです。
私はかつては完璧主義者でした(ソリューションではなく、フレームワークの作成に時間を費やしていました)。
しかし、私が本当に生産を加速するのに役立ったのは、原則として外部を含むBDD / TDDの原則を学び、それに従うことでした(これを受け入れることを学ぶのは特に難しいと感じました)。
これは、テストが存在する前にコードを1行も書かないことを本当に教えてくれました。ただし、単体テストは、受け入れテストが存在する前には存在しません。そして、受け入れテストは、実際のユーザーのニーズに基づいています。
したがって、すべてのコード行は実際のユーザーのニーズに基づいています。
原則として外部に精通していない場合は、テストダブルを使用して下位層の動作をシミュレートして、アプリケーションの最も外側の層(つまり、ほぼすべての場合のGUI)のテストの作成を開始する必要があります。次に、テストに合格するのに十分なだけ実装します。次に、この最上層の実装により、アプリケーションの最下層に到達するまで、次の層などに書き込む必要があるテストが決まります。
私は経験によってこれで良くなることに気づきます。
私が(非常に)若かったとき、私は常に妥協のない最も完璧な解決策を求めました。今、私は予算や時間のようなことを念頭に置いて良いです。
時間制限により、この線は非常に明確になります。
私の上司は実際に:)
私は良くなっていることを認めなければなりませんが、私はまだ妥協することはあまりありません。ありがたいことに、私は上司を手に入れました;)
オーバーエンジニアリングは非常に簡単に検出できるため、オーバーエンジニアリングよりも別の問題を提起したいと思います。
私の主な問題はリファクタリングです。問題は、ほとんどの場合、可能な限り良いコードを書き込もうとしても、当時知っていたことを知らなかったということです(より多くのコード、より多くのパターン、新しいイディオム、新しい問題、新しいソリューション)。それで、たとえそれが機能していても、私は今より良い方法を知っています:
ただし、そのまま機能しているため、リファクタリングは優先事項ではありません。真実は、それが私を悩ませていることです。私は経済的な理由を理解しており、クライアントの期待は理解しています(コードは表示されず、新機能やバグ修正を好みます)が、まだ作業する時間があればいいのにと思います。
今のところ、私は上司の命令に従うだけですが、本番環境に配信されたコードが今思いつく最高のものではないことに不安を感じていることを認めなければなりません。完璧主義。
専門的にも個人的にも、私が自分に適用しようとする基準は次のとおりです。
勝利に満足してください。
私のコードが問題を解決するのであれば、それは解決することを意図しているものであり、新しい問題を作成することはありません*。設定する必要があるほど高いバーを設定することを学ぶと、「十分」が十分になります。
完璧さは光の速度のようなものです。そこに到達することは決してありませんが、試して費やすことができるエネルギーに制限はありません。
(*-「バギー」と「維持するのが難しい」の両方が「新しい問題」という見出しにしっかりと分類されることに注意してください。最新のコメント/ APIドキュメント。)
経験を積むと、特定のコンテキスト(言語、フレームワーク、プラットフォーム、標準)で少なくとも数年、完全性を実現することさえできないことに気付きました。初心者として、あなたが気付かないであろうあらゆる種類の特異性があります(エスケープ、優先順位、予約語、構文糖、タイムアウト、非同期呼び出し、文書化されていない機能とバグ)。可能な限り学びながら。重要なことは、結果のリファクタリングを簡単にすることです。モジュラーアーキテクチャ、必要に応じてコメント、そして巧妙なトリックはありません。
私は、他の多くのプログラマーと同様に、維持すべき多くのレガシーコードを持っています。すべてをやり直す誘惑は常にそこにありますが、私は本質的に1つの原則に要約しました:
私(または他の誰か)は、これをもう一度理解する必要がありますか?
これは通常、多くのスパゲッティコードを処理して、より管理しやすいスパゲッティチャンクコードにします。いくつかのチャンクを抽象化して、テストを投入します。今では、完璧を必要とするものはそれほど多くありません。