最近のコードレビューで、クラス内の重複したロジックの数行(15行未満)を見つけました。著者がコードをリファクタリングすることを提案したとき、彼はコードがそのように理解するのがより簡単であると主張しました。コードをもう一度読んだ後、複製されたロジックを抽出すると読みやすさが少し損なわれることに同意する必要があります。
DRYはガイドラインであり、絶対的なルールではありません。しかし、一般的に、DRYの名の下に読みやすさを損なうことをいとわないでしょうか。
3つのルール
初めて何かをするときは、それをするだけです。 2回目
似たようなもの、あなたは複製にひるむが、あなたは複製をする
とにかく何か。 3回目に同様のことを行うときは、リファクタリングします。
3回のストライキで、リファクタリングします。
Seibel:したがって、これらのXII呼び出しのそれぞれについて、実装を記述しています。
非常によく似たコードをたくさん蓄積していることに気付いたことがありますか?ザウィンスキー:ああ、そうだね。通常、2回目または3回目までにカットアンドペーストします
そのコードは、切り取りと貼り付けを停止してサブルーチンに入れる時間のようなものです。
私は何も容認しません。時間の制約などで、いくらか持ってしまうかもしれません。しかし、重複したコードが本当に正当化されるケースはまだ見つかりません。
読みやすさが損なわれると言っても、名前を選ぶのが苦手だということを示唆しているだけです:-)
個人的には、何よりもまず、コードを理解できるようにしておくことを好みます。
DRYは、コードのメンテナンスを容易にすることです。繰り返されるコードを削除するためにコードを理解しにくくすると、多くの場合、コードの行が繰り返されるよりも保守性が損なわれます。
そうは言っても、実用的な場合、DRYに従うのが良い目標であることに同意します。
問題のコードに明確なビジネスまたは技術サポートの目的Pがある場合は、通常、それをリファクタリングする必要があります。そうしないと、クローンコードに関する古典的な問題が発生します。最終的には、Pをサポートするコードを変更する必要があり、それを実装するすべてのクローンが見つかるわけではありません。
一部の人々は、3つ以上のコピーがリファクタリングのしきい値であると示唆しています。 2つある場合は、そうする必要があると思います。大きなシステムで他のクローンを見つけること[またはそれらが存在する可能性があることを知ることさえ]は、2つまたは3つ以上あるかどうかにかかわらず困難です。
現在、この回答は、クローンを検索するためのツールがないという状況で提供されています。クローンを確実に見つけることができれば、リファクタリング(メンテナンスエラーを回避)する元の理由はあまり説得力がありません(名前付きの抽象化を持つことの有用性は依然として現実的です)。本当に必要なのは、クローンを見つけて追跡する方法です。それらを抽象化することは、(見つけるのを簡単にすることによって)それらを「見つける」ことができるようにする1つの方法です。
クローンを確実に見つけることができるツールは、少なくともクローンの更新に失敗したメンテナンスエラーを防ぐことができます。そのようなツールの1つ(私は作成者です)は CloneDR です。 CloneDRは、ターゲット言語構造をガイダンスとして使用してクローンを検索するため、空白のレイアウト、コメントの変更、変数の名前変更などに関係なくクローンを検索します(C、C++、Java、C#、COBOL、PHPなどの多くの言語に実装されています)。 CloneDRは、ガイダンスが提供されることなく、大規模なシステム全体でクローンを検索します。検出されたクローンと、antiunifierが表示されます。これは、基本的に、代わりに記述した抽象化です。そのバージョン(COBOL用)はEclipseと統合され、バッファー内のクローン内で編集しているとき、および他のクローンがどこにあるかを示し、そこにいる間に他のクローンを検査/改訂できるようになりました。 (あなたがするかもしれない1つのことはそれらをリファクタリングすることです:)。
以前はクローン作成はまったく間違っていると思っていましたが、クローンが元のクローンとどのように異なるかわからないため、クローン作成が行われている時点で最終的な抽象化が明確ではないためです。クローンを追跡でき、抽象化が明らかになった後でリファクタリングを試みることができれば、クローンは良いと思います。
繰り返すとすぐにanything間違いを見つけた場合は、編集を行うための複数の場所を作成し、それを拡張、編集、削除、またはその他の数十の場所を追加する必要がありますあなたがその力に直面するかもしれない理由は変化を強制します。
ほとんどの言語では、適切な名前のメソッドにブロックを抽出しても、読みやすさが損なわれることはめったにありません。
それはあなたの標準を備えたあなたのコードですが、あなたの「いくらですか?」に対する私の基本的な答えです。 isnone.。
リファクタリングは難しい場合があり、これは言語によって異なります。すべての言語には制限があり、複製されたロジックのリファクタリングされたバージョンは、繰り返されるコードよりも言語的に複雑になる場合があります。
多くの場合、コードLOGICの重複は、基本クラスが異なる2つのオブジェクトの動作方法が類似している場合に発生します。たとえば、両方とも値を表示するが、その値にアクセスするための共通インターフェイスを実装していない2つのGUIコンポーネント。この種のシステムをリファクタリングするには、必要以上にジェネリックオブジェクトを取得し、その後に型チェックとキャストを行うメソッドが必要です。そうでない場合は、クラス階層を再考して再構築する必要があります。
この状況は、コードが正確に複製された場合とは異なります。同じ関数内で2回だけ使用することを意図している場合は、必ずしも新しいインターフェイスクラスを作成する必要はありません。
どの言語かは言いませんでしたが、ほとんどのIDEでは、単純なリファクタリング->抽出メソッドです。それはどれほど簡単であり、いくつかの引数を持つ単一のメソッドは、重複コードの2ブロックよりもはるかに保守しやすくなっています。
抽象的に言うのは非常に難しい。しかし、私自身の信念は、重複したコードが1行でも関数にする必要があるということです。もちろん、私はいつもこの高い基準を自分で達成するとは限りません。
一般的にはありません。とにかく読みやすさのためではありません。複製されたコードを、本のように読む一般的な方法であるIMOを明らかにする意図にリファクタリングする方法は常にあります。
依存関係の導入を避けるためにDRYに違反することについて議論したい場合、それはより重要になる可能性があり、ポイントを説明するためのコードとともにAyendeの意見を得ることができます ここ 。
あなたの開発者が実際にAyendeでない限り、私はDRYに固執し、意図を明らかにする方法を通じて読みやすさを取得します。
BH
DRYのポイントは保守性です。コードが理解しにくい場合は保守が難しいため、リファクタリングが読みやすさを損なう場合は、実際にはDRYの目標を達成できない可能性があります。15行未満のコードの場合、私はあなたのクラスメートに同意したいと思います。
重複するコードは受け付けません。何かが複数の場所で使用されている場合、それはフレームワークの一部、または少なくともユーティリティライブラリになります。
最良のコード行は、書かれていないコード行です。
それは実際には多くの要因、コードの使用量、読みやすさなどに依存します。この場合、コードのコピーが1つだけで、この方法で読みやすい場合は、おそらく問題ありません。しかし、3番目に同じコードを使用する必要がある場合は、それを共通の関数にリファクタリングすることを真剣に検討します。
可読性はコードが持つことができる最も重要なものの1つであり、私はそれについて妥協したくありません。重複したコードは悪臭であり、大罪ではありません。
そうは言っても、ここには問題があります。
このコードが偶然に同じではなく同じであると想定される場合、保守性のリスクがあります。それぞれの場所に他の場所を指すコメントがあり、3番目の場所に配置する必要がある場合は、リファクタリングします。 (実際には、適切なコードファイルを共有しない2つの異なるプログラムにこのようなコードがあるため、各プログラムのコメントは他のプログラムを指しています。)
線がまとまりのある全体を作り、簡単に説明できる機能を実行するかどうかについては、まだ述べていません。もしそうなら、それらをリファクタリングします。コードが2つの場所に埋め込まれている方が読みやすいことに同意するため、これが当てはまる可能性はほとんどありません。ただし、より大きなまたはより小さな類似性を探し、コードを単純化するために関数を除外することもできます。十数行のコードが繰り返されているからといって、関数がその十数行で構成されている必要があるとは限りません。