DRY原則の違反


10

このアンチパターンの名前はどこかにあると思います。しかし、私はそれを知るためのアンチパターン文学に十分に精通していません。

次のシナリオを検討してください。

or0クラスのメンバー関数です。良くも悪くも、それはクラスメンバー変数に大きく依存しています。プログラマAがやってきて、をor0呼び出すのor0ではなく、クラス全体をコピーして名前を変更するような機能が必要です。私がor0言うように、それはその機能のためにメンバー変数に大きく依存しているので、彼女が呼び出さないと思います。または、彼女はジュニアプログラマであり、他のコードから呼び出す方法を知りません。これでor0c0(コピーの場合はc)が得られました。私はこのアプローチでプログラマーAを完全に責めることはできません。全員が厳しい納期に直面し、コードをハッキングして作業を完了させます。

何人かのプログラマーがメンテナンスしているor0ので、バージョンになりorNます。 c0現在バージョンcNです。残念ながら、クラスを含むクラスを維持しているほとんどのプログラマーはor0完全に気付いていないようでしたc0-これは、DRY原理の知恵について私が考えることができる最も強力な議論の1つです。また、のコードの独立した保守もあった可能性がありますc。いずれにせよ、と思われるor0c0、互いに独立して維持しました。そして、喜びと幸せ、エラーはで発生しcNていないのに発生していますorN

だから私はいくつかの質問があります:

1.)このアンチパターンの名前はありますか?私はこれが起こるのを見たので、これが名前付きのアンチパターンではないと信じるのは難しいことがよくあります。

2.)私はいくつかの選択肢を見ることができます:

a。)orN必要なすべてのメンバー変数の値を指定するパラメーターを取るように修正。次に、必要なすべてのパラメーターを渡しcNて呼び出すように変更しますorN

b。)からorNに修正を手動で移植してみてくださいcN。(私はこれをしたくありませんが、現実的な可能性があります。)

c。)orN-- cNagain、yuckに再度コピーしますが、完全を期すためにリストします。

d。)どこcNが壊れているかを把握し、とは独立して修復しorNます。

代替aは長期的には最良の修正のように見えますが、お客様がそれを実装することを許可するかどうかは疑問です。物事を正しく修正するために時間やお金を費やすことはありませんが、同じ問題を40または50回修復するための時間とお金は常に必要ですか。

誰かが私が考慮しなかったかもしれない他のアプローチを提案できますか?


「このアンチパターンに名前はありますか?」「違反ドライ」アンチパターン?:)私見あなたはほとんど自分で答えました。
Steven Jeuris

多分それを「乾いた違反者」と呼んでもいいですか?
FrustratedWithFormsDesigner

2
私はそれを呼びます:DRYバンピング。
AJC 2011

5
コーディングをコピーして貼り付けますか?
tylermac '12

これは「料理人が多すぎるとスープがだめになる」パターンと呼ばれます。
Doc Brown

回答:


18
  1. これは単に重複コードと呼ばれます -これについては、これ以上の凝った名前は知りません。長期的な影響は、あなたが説明したとおりであり、さらに悪いことです。

  2. もちろん、可能な限り重複を排除することが理想的な選択肢です。かなり時間がかかる場合があります(最近のレガシープロジェクトの場合、クラス階層内の20を超えるサブクラスにわたっていくつかのメソッドが複製されていました。その多くは、長年にわたって独自のわずかな違い/拡張を進化的に成長させていました。すべての重複を取り除くために、連続したユニットテストの作成とリファクタリングを行ってから約1.5年かかりました。

    そのような場合でも、重複の排除に向けて動き始めたとしても、一時的な修正として他のオプションを1つ以上必要とする場合があります。しかし、どちらがより良いかは、多くの要因に依存し、より多くのコンテキストがなければ、推測しているだけです。

    小さな改善がたくさんあると、長期的には大きな違いが生まれます。必ずしも顧客がこれらを明示的に承認する必要はありません。バグを修正したり機能を実装したりするために上記のクラスに触れるたびに少しリファクタリングを行うと、時間の経過とともに長い道のりを進むことができます。タスクの見積もりにリファクタリングのための時間を追加してください。長期的にソフトウェアを正常に保つことは、標準のメンテナンスと同じです。


3
+1、重複するコードについて言及する場合だけでなく、コードのリファクタリングのストーリーに関わるまったくの努力のため。:D
Andreas Johansson

9

WET(We Enjoy Typing)パターンへの参照がありますが、それが標準の名前であるかどうかはわかりません。

...ソフトウェアライセンスは、DRY(Do n't Repeat Yourself)プラクティスの注目すべき例外です。ソフトウェアライセンスコードは、できるだけWET(We Enjoy Typing-DRYの反対)にする必要があります。

ライセンスロジックを1か所に分離し、他の問題から分離すると、ソフトウェアを変更してライセンスを完全に無効にすることがはるかに簡単になります。ライセンスロジックをアプリケーション全体で何度も繰り返すことをお勧めします。できれば、ソフトウェアの1回の実行中に何度も実行されるようにします。

たとえば、インストール中、アプリケーションの起動中、および重要な機能にアクセスするたびに、ライセンスチェックを実行することをお勧めします。起動時にライセンスを一度チェックしないで、その値を渡してください。代わりに、実際に各エリアでライセンスチェックを複製します。それは不便ですが、簡単に解読できる製品をリリースするよりはるかに優れています...


3
WETの意味:「すべてを2回書く
StuperUser」

1
@StuperUser昨日dailywtfで...
jeremy-george

3

私がきちんとあなたを理解しているなら、クラスではあまりにも多くのことが起こっています。これにより、単一責任の原則に従わない方法が作成されます。移動する必要のあるコードにつながり、他の人たちが取り除いた間に取られた部分。これにより、多くのメンバーが作成されることもあります。

アクセシビリティ修飾子も確認する必要があります。公開されているもの、実際には公開されているものを確認します。消費者は小さなメンバーすべてについて知る必要はありません...カプセル化を使用してください。

これにはリファクタリングが必要です。また、コードは事前設計なしで書かれているようです。テスト駆動開発を調べます。実装されているコードを呼び出すのではなく、コードを呼び出す方法を記述します。タスクを実行する方法に関するヒントについては、TDDを調べてください。


3

コードをコピーする場合は、二重メンテナンスの技術的負債、具体的にはコードの複製を導入します。

通常、これはリファクタリングによって修正されます。より具体的には、すべての呼び出しを、共通のコードを持つ新しい関数(または新しいクラスの新しいメソッド)にリダイレクトします。開始する最も簡単な方法は、コピーされたすべてのコードを削除し、何が壊れているかを確認することです。この場合、呼び出しを共通コードにリダイレクトすることで修正します。

コードをリファクタリングすることに顧客に同意してもらうことは、技術的でない人に技術的負債を修正するように説得するのが難しいので難しいかもしれません。したがって、次に時間の見積もりを出すときは、見積もりにリファクタリングするのにかかる時間を含めてください。ほとんどの場合、修正を行っている間、コードのクリーンアップを行っていると顧客は思っています。


1

私にはスパゲッティコードのように聞こえます。最良の修正は、リファクタリング/書き換えです。

特に、多くのGOTO、例外、スレッド、または他の「非構造化」分岐構造を使用するものなど、複雑で絡み合った制御構造を持つソースコードの軽蔑的な用語。プログラムフローは概念的にスパゲッティのボウルのように、つまりねじれて絡み合っているため、このように呼ばれています...

http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Spaghetti.jpg/175px-Spaghetti.jpg


-1リファクタリングとリライトは2つの非常に異なるオプションです。ソフトウェアを捨てて完全に書き換えることは決して良い考えではありません。joelonsoftware.com/articles/fog0000000069.html
P.Brian.Mackey

1
スパゲッティコードはIMOの方がはるかに一般的で、緩い用語です。このようなコードには重複が含まれていることがよくありますが、重複することなくスパゲッティコードを作成することができます。
ペーテルTörök

@ P.Brian.Mackeyリファクタリングとリライトが同じものだと言ったことはありません。OPはどちらを使用するかを決定する必要があります。
トムスクワイアー

2
私はその記事のファンではありませんでした。引用した例では書き換えが悪い考えであったことに同意しますが、その例でそれが悪い考えだったからといって、それが常に悪い考えであるとは限りません。手始めに、書き換えを行うことで他の進行が妨げられますか?もしそうなら、それは悪いです。そうでない場合は、それはそれほど悪くはありません。
ジョッキング

@jhocking-書き換え禁止ポリシーの要点は、他のプログラムの進行をブロックすることではなく、実際の修正が時間とともに失われることではないと私は信じています。その不思議な「if(goldenNugget> 22)」は、名前が不十分であるにもかかわらず、何時間も何日も研究しないと特定するのが難しい特定の問題を解決します。今、その同じデータを取り、それを改善することは、代わりに行われるべきものです。それはリファクタリングです。捨てて「今度はやる」と言うのは時間の無駄です。既に解決済みの問題を解決するのと同じ理由が時間の浪費です。悪いコードの上に良いコードを追加すると負債が増える
P.Brian.Mackey

0

Aを完全に責めることはできないと言いますが、実際にこの方法でクラスをコピーすることは許されません。これは、コードレビュープロセスの大規模な失敗です。これはおそらく最も大きな障害であり、コードレビューはまったくありません。

期限に間に合うようにひどいコードを作成する必要があると思った場合は、その後のリリースで最も優先度の高いリクエストは、ひどいコードを今すぐ修正することです。だからあなたの問題はなくなりました。

DRYの原則は、完全ではなく、改善できる状況向けです。クラスを複製することはまったく新しい能力です。私は最初にそれを「重複コード」と呼んでいますが、時間が経つにつれて、最悪の時間の無駄、「発散重複コード」に変わります。同じコードの複数のコピーはほとんど同じですが、まったく同じではなく、誰も知らない違いは意図的、偶然、またはバグです。


-3

このパーティーには10年近く遅れていますが、このアンチパターンの名前はDivergent Changeです。この場合、複数のクラスに同じ動作のコピーが含まれますが、時間とメンテナンスの進行と一部のクラスが忘れられると、それらの動作は分岐します。

共有される動作とその共有方法に応じて、代わりにShotgun Surgeryと呼ぶことができます。ここでの違いは、単一の論理機能が単一の機能ではなく、多くのクラスによって提供されることです。


1
これは同じようには見えません。発散変化とは、同じクラスに多くの変更が加えられたときです。OPはコードの重複を記述します。Shotgun Surgeryも同じではありません。Shotgun Surgeryは、いくつかの異なるクラスに対して行われた同じ変更について説明しています。
Robert Harvey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.