web-dev-qa-db-ja.com

プログラミング中のリファクタリング

問題が発生した場合、特にそれが本質的に複雑である場合は、問題を解決するために取るアプローチについて、少し時間をかけて考えます。これにもかかわらず、よくあることは、ソリューションをプログラミングしているときに、見逃した問題の詳細について考え始め、それに応じてコードを調整することです。

結果として生じるのは、リファクタリングが必要なコードの混乱です。

私は「リファクタリング」をしたいのですが、簡単に聞こえますが、それを実行するのは本当に大変です。私が見逃した詳細が小さい場合、私がすでに書いたものを消去して、それを想定どおりに書くのではなく、私のデザインに小さな更新を加えたくなります。

明白な答えのある質問のように聞こえますが、「リファクタリング」を改善するために使用するテクニックはありますか?これが良い原則であることは知っていますが、何度も失敗します。

9
Kirby

おそらく、Fowler's Refactoring本の基本的な観察は、コードの動作に影響を与える変更とそうでない変更を分離する方がはるかに良いことです。後者のカテゴリーのものを「リファクタリング」と呼びます。これらの変更を混ぜると、混乱してしまいます。そうしないでください。コーディングモードとリファクタリングモードを切り替えることはできますが、両方を同時に行うことはできません。しようとすると、何を間違えたのかわからないからです。

動作を変更する変更を導入しようとしても、動作が変更されない場合:何か間違ったことをしました。確認して修正してください。多分ちょうどそれをロールバックします。

リファクタリングを導入しようとすると、動作doesが変更されます。確認して修正してください。たぶんそれをロールバックするだけです。

両方の変更を同時に試みた場合、その単純な評価を行うことはできません。単体テストがない場合も同様です。それらを書く。そして、一度に1つのことを行います。

17
Carl Manaster

これが私がよくすることです:コメントとして、あるいはコメントアウトされたコードとして自分自身にメモを残してください。ずさんなコードが機能するようになったら、簡単に再編成できます。

また、リファクタリングに本質的に問題はありません。続行する前に、リファクタリングされたコードが新しいバグを引き起こさないことをテストする方法があることを確認してください。

6
Luke Dennis

別の経験則では、すべてのメソッドは1つのことだけを実行する必要があります。

実装しようとしているものの処理を小さな個別のステップに分解し、それらのステップをメソッドとしてコード化すると、リファクタリングのタイミングになったときに、意味のある唯一のリファクタリングがメソッドが呼び出される順序、または一部のメソッドを実行パスから除外する順序。

また、メソッドは離散的であるため、返される値が本来あるべき値である限り、単一のメソッドを自由にリファクタリングできます。他のコードは、変更が行われたことを賢くすることはできません。

これにより、メソッドをあちこち最適化するだけで、コードを徐々に改善していくための準備が整います。全体的なロジックは変更されず、特定のステップの詳細のみが変更されます。

これをメソッドからクラスにフォローアップすると、クラス内で単一のオブジェクトのみを実行または表す場合、メソッドの場合と同様に、リファクタリングはクラスが構築および使用される順序の単なる再編成になることがわかります。 、詳細ロジックを実際に変更することについてはあまり説明しません。

プログラムの仕様が大幅かつ突然変更されたときにスイートスポットに到達したことはわかっていますが、オブジェクト間の関係を変更するだけで、必要な変更のほぼすべてに対応できます。内部実装をまったく変更する必要はありません。突然ニルヴァーナを手に入れたような気がします!

頑張ってください。すべてのコードにバグがない可能性があります。

ロドニー

5
rpbarbati

コードの単体テストが役立つ場合があります。

3
Edson Medina

問題を解決するためにトップダウンのアプローチを取るかのようにインターフェイスを作成しているのに、ボトムアップで実装している可能性はありますか?もしそうなら、それはあなたに問題を引き起こしている論理的なミスマッチだと思います。

あなたが説明していることに基づいて、あなたがする必要がある少なくとも一つのことを考えることができるように問題を分解し、そしてそれだけを実装するほうが良いかもしれません。あなたがしなければならない別のことを考えて、それを実行してください。続けて、最初に絶対的なファンダメンタルズを記述し、次にそれらの上にあるビルディングブロックを上向きに記述して、実際のソリューションが確定するまでソリューションを構築します。私は、難しい問題に対してさえ、完全な解決策があなたに忍び寄り、その種のアプローチに従うと突然飛び出す傾向があることに気付く傾向があります。

中間の構成要素を論理的に集中させ、コードの各セグメントを意図的に閉じて制限しておく場合は、実行する必要があるリファクタリングの量を常に小さく分離する必要があります。

2
Tommy

...私がすでに書いたものを消して書くのではなく、私のデザインに小さな更新を加えたくなります本来あるべき姿

何も想定されていません。想定される唯一のことは次のとおりです。

  1. あなたができること任意あなたが望むこと
  2. あなたの生涯/労働時間は限られており、限られた数の物にしか到達できません。

なんでしょう? 1つは完全に完璧なsuper-duper-excellent-clean-codeプロジェクト、または3つの完成したプロジェクトは前者と比較してわずか70%のコードエレガンスですが、ユーザーの観点からは95%の3倍ですか?世界、あなたの人々、あなたの使命のためにより役立つものは何ですか?

何が欲しい?

もちろん、長期的には、リファクタリング(mtce時間の短縮など)に見返りがあるかもしれませんが、それは長い時間でのみです。私たちプログラマーは、必要とされるよりもはるかに早くリファクタリングと最適化を試みようとすることがよくあります。それ以上開発されていないコードをリファクタリングすることがよくあります。これは、時間の浪費を意味します。

私は2〜3の独自の黄金律を使用します。特定のコードの最初の使用法では、できるだけ早くそれを攻撃します。ユースケースの可能性に関する十分な情報がまだないため、それのより一般的な使用法について考えることはほとんど効果がありません。また、コードのこの部分は二度と使用されない可能性があります。コードが2度必要になるとき、私は最初のコードをこのケースにも適用できるように一般化するか、それをコピーすることを選択します(ただし、これは好きではありません)。 3回目の使用では、リファクタリングするのに十分な情報があると感じています。コードのこの部分は実際に使用されているように見えるので、効果があると感じています。

1
Tomas

結果として生じるのは、リファクタリングが必要なコードの混乱です。

あなたがそれを理解するまで、ただ問題を吹き飛ばしてください。次に、その形式がわかったら、新鮮で正しい実装を作成します。

より一般的な用語で質問に答えるには:必要な変更を行うと、一般的には、後で行うよりも早く行うと、リップル/再テストが少なくなることを思い出してください。

0
justin