4

つまり、コードを DRY することは良いことだと思われますよね? 私が取り組んでいたプロジェクトの 1 つに、使用されているコンテキストを除いて多かれ少なかれ同じモデル/エンティティが存在する状況がありました。つまり、そのようなすべてのエンティティには、タイトル、説明、タグ、user_id など、その他の属性がありました。したがって、それぞれのコントローラーでの CRUD アクションは非常に似ています。

私のマネージャーは、コードの繰り返しであり、DRY する必要があると主張しました。includeそこで彼は、 d がこれらすべてのエンティティーのコントローラーの CRUD アクションを処理する CRUD ruby​​ モジュールを思いつきました。しかし、最終的にはシンプルさが損なわれました。すべての「もの」が「オブジェクト」と名付けられたため、コードは可読性を失いました。デバッグが難しくなり、コードを DRY する必要がなくなりました。

これはほんの一例でした。それらのいくつかは、ドライアップが複雑でデバッグしにくいコードをもたらしたものです。問題は、いつコードの DRY をやめるべきかということです。コードの単純さが失われていることに毎回気付くとは限らないためです (コードの作成者は、コードの単純さが失われていることにまったく気付かないことがよくあります)。また、シンプルさとドライ コードのどちらかを選択する必要がある場合、どちらか一方しか取得できない状況が発生した場合、何を選択する必要があります。

4

8 に答える 8

4

私の理解では、コードを DRY することでシンプルさが失われているのであれば、私たちは何かひどく間違ったことをしているのです。繰り返され、単一の責任を持つコードをDRYする必要があると思います。コードの責任が異なる場合、および/またはエンティティの抽象化に名前を付けることができない場合、コードを繰り返していません。コードパターンは繰り返されるかもしれませんが、それは独自の責任を持つ完全に異なるコードです。DRYing の結果があいまいなコードになっている場合は、似たようなパターンを持つさまざまな責任を持つコードを DRY しようとしている可能性がありますが、これは実際には良い習慣ではありません。DRYing はシンプルさを抑圧するのではなく、強化する必要があります。

于 2009-10-07T06:20:32.470 に答える
0

DRY 原則の目的は、コードの「品質」を向上させることです。

変更によってコードの品質が向上しない場合は、停止するときです。これを判断する能力は経験によってもたらされます。要件が変わると、コードをリファクタリングする最も適切な方法も変わるため、すべてを理想的なものにすることは不可能です。少なくとも、最初に要件を確定する必要があります。

コードのサイズを最小化することは、コードゴルフをしている場合を除いて、一般に品質を考慮する必要はありません。そのため、コードのサイズを縮小することが唯一の目的である場合は、DRY を実行しないでください。

複雑なトリックは、効果よりも害を及ぼす可能性があります。

于 2009-10-07T08:32:07.943 に答える
0

保守性を向上させるために DRY を適用する主な理由は、コードの変更が必要な場合に、その変更を 1 か所で行うだけで済むようにすることです。これにより、必要な場所で変更が行われないというリスクを回避できます。

しかし、私はすべての話をしているわけではありません:

Dave Thomas とのこのインタビューでは、DT が次のように述べています。

DRY は、システム知識のすべての部分が、信頼できる明確な表現を持つべきだと述べています。

「DRY」を初めて見たのはThe Pragmatic Programmerだったので、これについては Dave と一緒に行きたいと思っています。

ここに読む価値のある別の記事があります

しかし、DRY は原則であり、規則ではありません。原則を理解すればするほど、それを適用すべき状況を認識できるようになります。

(そして最後に、そのコードを「DRY」する前に、「多かれ少なかれ同じ」以上のものを望んでいると思います: 2 つのことが将来分岐する可能性がある明確な方法を見ることができればそれから私はそれらを放っておく傾向があります)。

于 2009-10-07T08:48:35.250 に答える
0

「デバッグ」の問題に関しては、補助フィールドを含めるためにそのような「基本クラス」を作成するとき、私は習慣になっています。このフィールドは、最も派生したクラスを識別する単純な文字列です (したがって、コンストラクタからコンストラクタに渡されます)。次に、各メッセージはこのフィールド + オブジェクト ID "realtype[id]" を出力し、すべてが突然デバッグしやすくなります。

いよいよDRYへ。

DRY には次の 2 点があります。

  • 階層の構築
  • 汎用コードの使用

最初の点は、これで十分に理解できるはずです。クラスのヒエラルキーとは、IS-A 関係を意味します。2 つのクラスが同様の動作をしているが、それ以外の点では機能的に無関係である場合、それらは同じ階層の一部であってはなりません (SHOULD NOT)。貧弱なメンテナーを混乱させ、可読性を損なうだけです。

2 番目のポイントは、特にスクリプト言語で、より頻繁に使用できます。前の例について言えば、クラスの階層を持つ代わりに、異なるクラスを取り (異なるビジネスをモデル化する) ジェネリック メソッドを単純に定義し、それらを一様に扱うことができると私は主張します。このようにして、繰り返し(DRY)を回避しながら、読みやすさ(私見)を犠牲にしません。

私の2カラット。

于 2009-10-07T06:27:22.313 に答える
0

可読性と保守性は、優れたコードの最も重要な 2 つの機能です。残念ながら、妥協が必要な場合もあります。これはバランスの問題であり、誰もが同意するわけではありません。

私自身も、あなたの視点に傾いています。コードが理解しやすいことを意味する場合は、明らかな繰り返しが必要です。

于 2009-10-07T06:21:19.330 に答える
0

誰かが私のコードに DRY が必要だと真顔で言ったら、私はおそらくそれを、彼らがやろうとしている他のすべてのことは本当にとてつもない、ためらいのあるものになるだろうという兆候として受け取るでしょう-それの。

そうは言っても、コードを書くことの単純さ (怠惰) とコード自体の単純さ (エレガンス) の間には違いがあります。ただし、バランスが取れていることには同意します。私は特定の時間にこの状況に陥りました(PHPで、しかし、それはあなたのジレンマをどのように思い出させますか):

$checked = ($somevariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $disabled_checked />";
$checked = ($someothervariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $checked />";

これは、私が扱っていたもののあまり良い例ではありません。基本的に、これは無線入力であるため、両方の入力にどちらがバブルインされるかを知る何らかの方法が必要でした。私は、あなたの上司が「湿気」の問題と呼ぶかもしれない問題があることを知っていたので、私は頭を悩ませていくつかの解決策を考え出そうとしました。優雅で要点があります。最後に上級開発者にそれを見せたところ、彼は「いいえ、すべて順調です。必要なことを実行します。余分な 1 行だけです」と言いました。

私は自分のプロジェクトを心配することで助けているというよりも、自分のプロジェクトを傷つけていたことを思い出して安堵しましたが、同時に、彼が基本的な原則についてとても無頓着だったことにまだ失望しています(まるでそれが彼の、私はそう確信しています)。

したがって、私も同意しますが、あなたのマネージャーはおそらくそれを行うためだけに何かを行っていたのでしょう。Ruby や Python のような優れた言語や Jquery のような優れたライブラリを手に入れることができるのは、より良い方法やアプローチを考え出すよう努めたときだけです。

基本的に、次の週thingsに 2 ではなく突然 70 になったらどうしますか? あなたの上司のオブジェクトがそれを簡単にするなら、彼は正しかった. それが同じ量の問題 (コードまたは実行) である場合、彼は間違っていました。しかし、だからと言ってシンプルにするよりも良い答えがないというわけではありません。

于 2009-10-07T06:39:08.343 に答える
0

私にとって、複製されたコードは、複数の起源を持つ可能性のある臭いです。

  • 変数の欠落 (変数の導入)。
  • メソッドがありません (式をメソッドにプッシュします)。
  • 羨望を特徴とします(行動を羨ましいクラスに押し下げます)。
  • 過剰な一般化 (ジェネリック クラスを特定の具象クラスに分割する)。
  • 抽象化が不十分です (属性と動作を新しいクラスにプッシュします)。

このリストはおそらく不完全です。出発点と考えてください。

重複を見つけたら、それがどのような問題を示しているかを考えてください。次に、その問題への対処に取り組みます。完了したら、新しいコードの読みやすさを検討してください。劣化している場合は、次のいずれかの位置にいる可能性があります。

  • 重複の根本にある問題を誤認しました (元に戻して、考え直して、もう一度やり直してください)。
  • 複製は必要なトレードオフです (変更を元に戻してそのまま使用します)。
  • あなたのソフトウェアは必然的に複雑です (変更をコミットし、それと共に生きます)。

可能であれば、このような質問とともにサンプル コードを投稿することを検討してください。それらは、回避するための具体的なものを提供します。そして、覚えておいてください、これらの多くは非常に主観的です.

于 2009-10-07T09:02:36.403 に答える