コーディング方法に問題があります。事前に計画をどれだけ作成するかに関係なく、コードはすぐに複雑になりすぎます。
優れた実践に関する本を読んで、その原則を守ろうとしてもうまくいきません。
計画段階でより綿密で専門的である以外に、コードを簡略化するためにコードを監査する確かな/証明された方法はありますか?
実際、コードを徐々に単純化し、そうすることでデザインを改善するための手法は確かにあります。一般的な手法は「リファクタリング」として知られています。この用語は、非公式に(「コードの機能を変更せずにコードの設計方法を変更するもの」を意味する)と正式に(「特定のリファクタリングの規律に従う」ことを意味する)の両方に使用されることに注意してください。ここでは後者の定義について言及します。
特に、この問題はMartin Fowlerによって多くの研究がなされており、彼の著書 " Refactoring:Improving the design of existing code "は、ソフトウェアエンジニアリングの古典的な本の1つであり、これを読む価値があります。範囲。
本が示唆する一般的なテクニックは次のとおりです。
1)リファクタリングするコードのセクションに対して非常に詳細なテストを記述します。
2)コードに特定の小さな変更を加えます。たとえば、メソッドのインライン化、クラスの名前の変更、新しいメソッドへのコードの抽出、既存のクラスからのスーパークラスの抽出などです(Fowlerは、このような多くの小さな変換の詳細なリストと、方法とタイミングに関する提案を書いています。 Eclipse、IntelliJなどの既存の「自動リファクタリング」機能の名前のほとんどは、彼の本で使用されているものから取られました。基本的に、これらは「デザインパターン」に似ていますが、既存のコードの変更に使用されますそもそもそれを設計するためのものではありません。)
3)テストを再実行して、まだ何も壊れていないことを確認します。
4)結果に満足するまで繰り返します。
このように、コードに大きな変更を加えるには、複数の小さな変更を累積し、変更ごとにテストします。
明らかに、そもそもコードの詳細なテスト(単体テストスイート、回帰テストスイートなど)を作成して保持する習慣がある場合、上記のプロセスは、テストを作成する必要がある場合よりもはるかに簡単です。リファクタリングを開始する直前。また、各変更の間に再実行するテストスイートの部分が非常に迅速に実行できる場合は、これを行う方がはるかに簡単です。
この方法でコードをリファクタリングすることはDISCIPLINEであることに注意してください。これは、単にコードをランダムに変更することと同じではありません。プロセス中の頻繁なテストは、プログラムの動作に加えた不注意による変更をすばやくキャッチし、実行内容を覚えておくために不可欠です。このため、プログラムの動作を追加または変更する他の開発とは別にリファクタリングを行うこともよくあります。これらの種類の変更は既存のテストを無効にする可能性が高いためです。たとえば、代替フェーズ:機能を追加してから、少しリファクタリングしてから、別の機能を追加して、さらにリファクタリングして、バグを修正してから、リファクタリングなどを行うことができます。
これらの手法を使用してコードを簡略化するプログラミングに一貫している場合、時間の経過に伴うコードの全体的な傾向は、逆(悲しいことに、業界ではより一般的)ではなく、徐々に単純で読みやすくなることです。
また、アジャイルやXPソフトウェア開発方法論を取り巻くコミュニティの一部は、リファクタリングの方法/時期/内容について役立つ場合があります。この方法での継続的なリファクタリングは、多くのそのような方法論の必要な機能。
多くのプロジェクトは徐々にだらしなく複雑になり、だれもそれを理解できなくなったので、最終的にはそれらを破棄する必要がありました。リファクタリングは、この問題を回避する方法です。
練習。
いや、本当に。
スパゲッティの最初のプレートまたは大きな泥のボールを書くまでは、本やブログの投稿のテクニックを完全に理解することはできません。これらのテクニックの多くは、その複雑さを和らげる効果的な方法であることに気づくでしょう。次に、それらをより深いレベルで理解します。パターンをひもでつなぎ合わせてクールに見せているが、その背後にある理由を完全には理解していない貨物カルト担当者よりもはるかに深いものです。
パターンを確認してください。簡単なものはありますか?まあ、それらはスパゲッティのプレートや泥の大きなボールを書いて、後でそれを維持する必要があるよりも間違いなく簡単です。ただし、これらのパターンを調査する必要があります。最高のペインターでさえ、複数のブラシを使用します。
私の確実な方法は:
コードが複雑になっているという最初のヒントで計画をリファクタリングすることを恐れていません。
(もちろん、これは、計画段階でより徹底的で献身的であることについてすでに述べた内容をまったく否定するものではありません。)
コードを Code Review に投稿し、他の誰かに簡略化してもらいます。 ☺
真剣に、何千ものコードレビューの回答の中で推奨されている簡略化を研究すると、テクニックの範囲が広すぎて回答に要約できないことがわかります。私の頭の真上から、私は考えることができます:
itertools
を利用して内包表記をリストします。)基本的に、@ RobertHarveyが言うように、練習。しかし、今では、他のプログラマーの経験を活用できるリソースを提供しています。
最も簡単な方法は、きれいなコードを作成するメンターを自分に連れて行き、面倒なコードを見せて、何が悪いのかを尋ねることです。
理解すべきことは、計画段階ではクリーンなコードは発生せず、クリーンなコーディング原則を継続的に「遵守」することはできないということです。定期的にのみリセットできます。あなた意志乱雑なコードを書く。それを認識したらすぐに修正します。コードをリセットする頻度が高ければ高いほど、コードは改善されます。
あなたは原則についての本を読んだと言ったので、あなたはそれらが何であるかを知っています。あなたはそれらにリセットすることについて系統的にすることができます。撤回する前に、原則を極端にしておくと役立つことがよくあります。楽器のチューニングと同様に、最初に通過した方が適切な設定値を聞き取りやすくなります。関数が長すぎる場合は、可能な限り最小の部分に分割します。thenを少し再結合します。
....番号。存在しない。
完全な解決策がないことは比較的明白であるので、そのようなものが存在するという考えをこれまで考えたことはありませんでしたが、あなたがそれについて言及したので...それは素晴らしいです!
しかし、いや、コードがひどく、速く、ゆっくりと、またはその間に(途方もなく?)ないことを保証する完璧な解決策はありません。
可能な限り、IDE(少なくとも)これらの2つのコンポーネントに付属)を使用してください:
本はwhyとhowを理解するのに最適です-whatとhowを無情にフェレットアウトするツールが必要です多く。
その後、作成したコードを定期的にチェックできます。関数の循環的複雑度が所定のしきい値を超えると、関数をリファクタリングします。等々。各開発サイクルに時間を置き、リファクタリングに専念します。それは可能な「時」です。時間と練習を重ねることで、リファクタリングのオーバーヘッドをより正確に見積もることができ、mostを修正することで、オーバーヘッドをほとんど自動的に減らすことができます。また、どのメトリック(およびその値)が最適かを確認することもできます。
(最後に、「オーバーヘッド」は誤ったラベルです-「コードを許可する小さくて快適な頭金notが巨額の技術的負債に入る可能性があり、将来のある時点でプロジェクトを破産する」と考えてください")。
私の経験では、ソフトウェア開発者がコードを書いているシステム/ドメインを正しく理解していない場合、コードは非常に複雑になる可能性が非常に高くなります。
この理由はかなり明白です。単純なコードは、解決される問題またはモデル化されるドメインを反映する構造を持っています。このようにして、コードの動作は、多数の明示的なケースとしてエンコードされるのではなく、構造から明らかになる傾向があります。
このエラーを見つけるもう1つの方法は、コードが適切に機能していることを確認するために多数のテストケースが必要で、あらゆる種類のEdgeケースで障害を発見した場合です。ソフトウェアが適切に設計されていれば、エッジのケースはそれほど多くありません。
したがって、モデル化している問題のドメインまたはシステムを理解しようと努力してください。他の誰かからの仕様や一連の要件を受け入れて、それをコード化するだけではいけません。ドメインの専門家とソフトウェアエンジニアの間の障壁を取り除きます。自分でドメインエキスパートになる。