Virtually all of us are guilty of copy and paste “reuse.” There are different types of reuse though and each come with their own set of problems and gotchas.
Copy/paste a method or large code snippet
This is the kind of reuse that almost everyone will agree is bad. When all is said and done there are two copies of the code. If a defect is found, it is likely to be fixed in one and not the other. Which is bad because an avoidable defect now stays in the code. This practice is hinting we should extract a new method and call it from the original code and our new code.
Copy/paste a code snippet and then change some values
While less blatant than the copy/paste a method code, it is still a code smell. This practice is hinting we should be refactoring into a new method that takes some parameters.
Copy/paste a code snippet and then change the body
This approach tends to be used for boilerplate code. One common example is copying the Java code for a regular expression replace loop and then changing the middle where the replace logic. In languages with closures, the need for refactoring is more glaring. In Java, it becomes a call on whether the reuse is worth it. For tiny examples, it tends to not be. For more complex examples, an inner class or inheritance is often the answer.
Copy/paste an idea
The hardest type of copy/paste reuse to detect is when it is on a conceptual level. A copy paste detection tool is unlikely to find it as the code wasn’t copy/pasted. This kind of copy/paste reuse occurs when someone is trying to figure out how to accomplish a task – say develop a DAO. Suppose the developer is new and doesn’t know what to do. The developer sees some code that loops through a result set and decide to use that idea. Then the developer sees some code that says getString() and copies that for all the types. This is all well and good until the data types aren’t varchars. Now the developer has getString() being used to get numbers and Dates too. Worse yet, this will not crash and appear to work. However, it will create other problems such as figuring out how to parse the date. If you were to ask the developer why they are using getString() instead of getDate(), the developer won’t know. This is fairly low level example. The same can happen on a higher level such as why the developer is using JDBC instead of JPA/entity beans/etc.
JavaRanch’s statement on Not being a code mill gets into this. Experts from the page “We are not, however, a code mill and make a point not to give out working code to someone who wants to … dump it into their project without knowing what it does. … that will help you to learn how to solve your problem using best practices.” I think this is an important point in all levels of reuse. While copy/paste reuse may appear to work at first, it doesn’t help in the long run.
When the copy/paste code causes defects in the future or needs to be modified, it needs to be understood. “I did it that way because some other code does” doesn’t make for a helpful reason to the team down the road.