コードの「コピーと貼り付け」が危険なのはなぜですか?[閉まっている]


130

時々、私の上司は私たちに文句を言うでしょう:

機能を実装するのになぜそんなに長い時間が必要なのですか?

実際、この機能は以前に別のアプリケーションに実装されています。そこからコードをコピーして貼り付けるだけです。コストは低くなければなりません。

コードのコピーと貼り付けは私の見た目ではそれほど簡単なことではないので、それは本当に難しい質問です。

これを技術者ではない上司に説明する理由はありますか?


19
以前のアプリケーションから新しいアプリケーションにコードをコピーして貼り付けるのではなく、同じ機能を何度も書き直しているようなものです。DRYの原則は、システム全体で同じ機能が重複しないようにすることを目的としていますが、他のアプリケーションのコードを再利用する方が、コードを再作成するよりも優れています。
カーソンマイヤーズ

5
コードをコピーして貼り付けるたびに、赤ちゃんのアザラシは殺されます。
DeadlyChambers 2014

@CarsonMyersコンポーネントが再利用可能な場合のみ。そして、それは現在の状況に適合することを意図しています。
Sreekanth Karumanaghat

回答:


171

コピーと貼り付けのコードにバグを見つけた場合は、行ったすべての場所でバグを修正する必要があり、すべてを覚えておくことができます(これは変更された要件にも当てはまります)。

ロジックを1か所に保持すると、必要に応じて変更するのが簡単になります(したがって、アプリケーションを更新する必要があると判断した場合は、1か所でのみ実行します)。

上司にDRYの原則を読んでもらいます(Do n't Repeat Yourself)。

あなたが説明していることは、コードを共有し、それを1か所にのみ保持する、ライブラリの完璧な使用法のように聞こえます。

コードをすぐにリファクタリングするつもりである場合に限り、コードをコピーして貼り付けます。できるだけ多くのロジックを再利用できるように、後で抽出した共通コードを確認します。そしてそのすぐ後までには、数日と数週間ではなく、数分と数時間後を意味します。


41
+1。重要なのは、差し迫った問題を解決するためにコピーアンドペーストが安価であることです。本当の問題は、中長期的には、複製されたコードを維持するコストが十分に分解されたコードよりはるかに高いということです
Paolo

7
これは単なるバグの問題ではありません。プログラムの要件は変更される場合があります。以前に何かを変更する必要があった5か所のうち4か所を変更しました。
David Thornley

1
オンデマンドでコピーアンドペーストが可能で、重複箇所を簡単に追跡して後で抽象化または更新できる場合は、コピーアンドペーストは悪いことではありません。詳細とこれを実行できるツールについては、www.semanticdesigns.com / Products / Cloneでクローン検出に関する説明を参照してください。
Ira Baxter

4
たくさんありますifsが、ほとんどのツールは現時点ではクローン検出をサポートしていません。
2010

2
むかしむかし、ESAで働くプログラマがいました。彼はAriane-5ロケット用のソフトウェアに取り組んでおり、コピーアンドペースト方式を使用していました。それからs ...が起こる
Hauleth 2013

25

あなたはコピーするよりもライブラリを構築することでコードを共有する方がはるかに良いでしょうコピーと貼り付けを使用てコードをコピー。

書き換え(DRYを検索)よりも速度が向上しますが、コードを維持する場所は1つだけになります。


1
気になるのですが、複製するだけでコードを「カット」できるのはなぜですか。
dpp、2014年

良い点dpp。編集しました!
CResults 2014年

12

明白な理由は、将来の「借金」を引き受けることです。コードで行う必要のある変更(バグ修正だけでなく、変更も)は、2か所を更新する必要があるため、実行にかかる費用が2倍になります。そして、そのうちの1つを最終的に忘れてしまうので、より危険です。言い換えると、今より速く動作させると、将来的にはさらに遅くなります。これ、ビジネスセンスとしては良いかもしれませんが、通常はそうではありません。

しかし、より重要な理由は、「これは同じです」という仮定が微妙に間違っているということではありません。暗黙の仮定が正しいことにコードが依存している場合は常に、コードを別の場所にコピーすると、これらの仮定が新しい場所にも当てはまらない限り、エラーが発生します。したがって、貼り付けられたコードは、次の変更の直後ではなく、最初から間違っていることがよくあります。


11

設計上、コピー貼り付けされたコードは確かに災害であり、将来、多くの問題を引き起こす可能性があります。しかし、なぜ今すぐに多くの作業を必要とするのかと尋ねると、答えは次のとおりです。それは単にコピーして貼り付けるだけではないからです。

元のコードが、柔軟性とクライアントの使用を念頭に置いて、かなり独立したライブラリとして再利用するために作成された場合、すばらしいですが、コピー貼り付けではなく、コードライブラリを使用します。実際のコードのコピーと貼り付けは通常、次のようになります。

  • 「確かに、私はすでにそれを正確に行うコードを持っています!」
  • 「ちょっと待って、これらの5つのバージョンのコードのうち、ソースとして使用したいのはどれですか?」
  • 「うーん、これらすべての「util_func_023」関数は何をするのですか?それらを文書化しませんでしたか?今のうちどれが必要ですか?」
  • 「ああ、そうです、このコードはコードベースYを使用しています。1つ選択する必要があると思います。コードベースYのすべてを新しいプロジェクトにコピーします。コードベースYに必要な関数の1つです。」
  • 「全部コピーしたよ、イェイ!」
  • 「なぜこれが機能しないのですか?」
  • これは、実際に開始したいコードを作成する代わりに、何時間/何日/何週間もの時間を費やして、希望するものに類似した既存のコードをデバッグするポイントです。

要約すると、直接使用できない既存のコードは、よくても、同様のコードを作成するための優れたリファレンスとして機能します。それは確かに全体を持ち上げることはできず、完全に異なるシステムで動作することが期待されます。一般に、作成されて完成したコードは、オリジナルではなくコピーであっても、可能な限り混乱させないことが安全な前提です。

あなたがコピー&ペーストであなたのプロジェクトをベースにする場合は、コードを持って開始するために、簡単に再利用を可能にするようにしなくてその元のコードをコピーし、それをいじり。それはやりがいのあることであり、それが上司が期待していることである場合は、どちらもあなたがそもそもそれが設計と作業の方法であることを確認する必要があります。


9

コピーと貼り付けは、発生するのを待っている災害です。上司は、壊れたコードをすぐにエンドユーザーに出荷した場合の価格と比較して、早期に出荷する場合の価格を評価する必要があります。


9

すでに機能を実装していて、それらを再利用するためにコピーして貼り付ける必要がある場合は、何か問題があったようです。これらの機能をライブラリに入れて、コピー/貼り付けなしで再利用できるようにできませんか?


8

DRY原則(Do n't Repeat Yourself): DRY on wikipedia

「すべての知識は、システム内で単一の明確で信頼できる表現を持たなければなりません。」

その他リンク


これは、「男性の喉にナイフを刺さないでください」と言っているようなもので、とても良いルールのように聞こえます。医師がこのルールを破る必要があると気づくまでは、男性の命を救うために開頭術を実行する必要があります(おそらくアナフィラキシーにより極端なアレルギー反応が起きて呼吸ができない場合)。すべてのルールには例外があります(ただし、おそらくこのルールを除き、すべてのルールに例外があります)。したがって、すべてのルールには、理由と時期と例外のリストがすべて添付されている必要があります。真の「エンジニアリング」の現実には、真の答えはそれによって異なります...
MicroservicesOnDDD

では、DRYをフォローしないのはいつですか?私は常に現在の仕事でこれに取り組んでいます。これはファームウェアに関するものであり、答えは「ループを展開する」など、「パフォーマンスが向上する」ためです。継承階層は非常に浅く、ほとんどのクラスをサブクラス化せずに直接使用しています。......コピーアンドペーストを頻繁に使用しています。そして、私はそれが嫌いです。なぜなら、それによってコードベースが理解しにくくなり、維持が難しくなるからです。しかし、私たちには理由があり、それらは許容できる理由です。私たちだけがステークホルダーではありません。そして、適切なバランスを見つけることは、より芸術的です。
MicroservicesOnDDD

7

技術者ではない上司が持っている最悪の誤解は、あなたの仕事が主にタイピングであるということです。タイピングをなくすことで時間を大幅に節約できると彼らは考えています。

この人に与えることができる最高の教育は、タイピングではないあなたのすべての仕事を指摘することです。その作業のほとんどは、通常、タイピングと同時に頭の中で目に見えない形で行われます。

確かに、タイピングをなくすことで時間を節約できます。しかし、それから、あなたの仕事のはるかに大きく、タイプのない部分が大きくなり、時間を節約するだけでなく、さらに多くの時間を消費します。


4

上司がDRYの原理、バグ、その他の技術情報について聞きたいと思いますか?

上司や会社がプロジェクトを完了するために必要な時間を過小評価したときに、あなたが通常聞くこの種のコメント。そして、誤った見積もりに基づいて契約が締結された、など。ほとんどの場合、プログラマーは見積もりに関与していませんでした。

なぜこれが起こるのですか?プロジェクトスポンサーの予算が少なすぎる場合があります。ソフトウェアを使用して自動化しているビジネスプロセスは、チームの努力に値しないかもしれません。そのような場合、マネージャーは一般的に悪いニュースのために非常に閉鎖される傾向があります。プロジェクトの最初には、希望的な考えがあります。次に、マネージャはプログラマを責めようとします。あなたの場合、コピーアンドペーストを介して間接的に。極端な場合、これは死の行進と呼ばれます。


3

コードのコピーと貼り付けは通常、偶然によるプログラミングにつながります


この記事は非常にひどく書かれていると思います。したがって、ナラティブは抽象的なままであり、フレッドが繰り返し作業しているという事実を超えて、この事件に光を当てることはできません。フレッドが抱える明らかな問題の1つは、彼が全体的なアーキテクチャをよく理解していないことです。残念ながら、これは、文書化されていないレガシーコードを使用してノウハウが失われた場合によく発生します。契約による設計およびアサーティブプログラミングへの参照は非常に優れていますが、残念ながらそれらの後でも、例/演習は説明されていません。
mapto

3

ここでは「別のアプリケーション」が重要だと思います。他のアプリケーションがすでにテストされて使用されている場合は、変更しないでください。て使用ている場合は、共通ライブラリを使用するし。そのため、コードを共有できません。

同じアプリケーション内では「コピーと貼り付け」は不適切ですが、異なるチームまたは異なるリリースサイクルで開発されたコードベース間では、「コピーと貼り付け」が最適なオプションです。


ライブラリを使用するためだけに他のアプリケーションの更新をリリースすることにはほとんど意味がないことがわかりますが、機能ブランチの必要な変更を少なくとも突き刺すことはおそらく良い考えでしょう。これにより、ライブラリのインターフェースが少なくとも問題の2つのアプリケーションに対して十分に一般的であるという確信が得られ、リリースサイクルの適切な時点で変更をマージできるようになります。
SamB 2012年

2

私は同じような会社で働いていました。研修生だったので、そのときのことをよく知りませんでした。そのため、私が新しいプロジェクトを始めたとき、上司もどこかからコードを貼り付けることを勧めました。まあ、ご想像のとおり、ソフトウェア全体がかなり混乱しており、バグを修正しようとすると、2つの新しいバグが現れました。


2

他のアプリケーションに必要な機能がすでにある場合でも、その機能のコードは、大幅な書き換えを行わないと、現在のアプリケーションに適合しない場合があります。それはフォードのモーターを取り、それをトヨタに適合させようとするようなものです。一般に、コピーするコードの25%以上を変更する必要がある場合は、最初から書き直す方が(安く)良いという経験則があります。

問題のコードをライブラリに抽出することは魅力的ですが、他のシステムの構築方法によっては、思ったより難しい場合があります。たとえば、その機能のコードは、他の多くのコードと(たとえば、多数のグローバル変数にアクセスするなど)不明瞭な方法でインターフェースするため、抽出が難しい場合があります。


1

上司に、すべての変数名の一部に古いプロジェクトの名前が含まれていることを伝え、今度はすべて手動で変更する必要があります。上司がコピー/貼り付けが悪い理由を知らない(または知りたい)場合は、上司もそれを信じているかもしれません:)


1

ええ、最大の問題は、単にコピーして貼り付けるだけではないということです。コピーして貼り付けて、少し変更してください。

その後、貼り付けられたバリアントの1つに問題があると、変更されます。その後、別のバリアントが変更されます。

次に、すべてのバリアントを変更する必要があることがわかり、元のコピーにバグがありました。これで、貼り付けられたすべての領域が同じではなくなったので、あなたは本当に本当にねじ込まれています。

そして、あなたはそれを知らないでしょう、この種のくだらないコーディングは通常ほとんど完全にコメントを欠いています。

私にとっての違いは、同じことを実行するコードの複数のコピーがある場合、あなたが持っているのはコードの束であるということです。特定の処理を実行するコードが1つしかない場合は、システムがあります。

システムの動作は、単一ポイントの変更で非常に簡単に変更できます。一連のコードの動作を変更するには、一連のコードが必要です。

コードの束ではなく、システムが好きです。


1

目の前にある機能の開発速度(特にアプリケーションが小さい場合)と、アプリケーションの成長に伴う長期的なメンテナンスコストの間にはトレードオフがあります。

コピーと貼り付けは、即時の機能に対してはより高速ですが、バグの修正、システム全体の変更、およびアプリケーションの異なるコンポーネント間のワークフローの維持の点で、アプリケーションのサイズが大きくなるにつれて、コストが高くなります。

それは事業主が聞く必要がある議論です。これは、一連の車両を維持するための許容コストに似ていますが、ソフトウェアでは、ソフトウェアアーキテクチャの壊れた部分は一般にビジネス側に隠され、開発者しか見ることができません。


0

チームが以前に同様の機能を実装している場合、それを繰り返すことは多くなるだろうと彼は正しい、2回目に簡単。

ただし、各アプリケーションが異なることをおそらく説明する必要があります。あなたが一つにドアを設置からといって家はあなたが別の家の中で別のドアをインストールすることができますという意味ではありません時間がないフラットあなたは(#ドアがインストールされている)ので、経験を速くなりますが、それはまだあなたの機器を取得するには時間がかかります- 、ドアを取り付け、それが垂直であることを確認し、フレームにねじ込みます。


0

私の会社では、クラスとメソッドを常に使用し、それらの技術ドキュメントを作成しています。私はあなたが以前に使用されたメソッドクラスを見つけるためにあなたが良いキーであなた自身のsvn検索アプリケーションを使用できるならそれがベストプラクティスだと思います:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.