While I know in a perfect world where a greenfield application was scoped out from day one with great BRD's and a competent development lead constantly reviewed code by their underlings to avoid this, I'm going to ask because we all know and have all been a part of plenty of scenarios where this isn't the case... and this happens...

The problem I run into all the time with consulting gigs is you'll find ten methods all pretty much doing the same thing, and with some refactoring, could be much more efficient. However, it doesn't seem to stop the developers from creating new methods when there's one already written, or mostly written they could use.

The problem doesn't always lie with the developer(s). If it's a large application, and even in a Service Oriented Architecture scenario, you could have hundreds of services and you're bound to have duplicates there because the other developer needed to accomplish something, was being a good little coder in making a reusable class/method, but wasn't aware another good little developer has already created that method.

So my question to you all is, what have you found to be the most successful way in avoiding duplicate methods? Documentation, Communication, Automated Refactoring? But more important, how to clue in other developers coming into an existing application project with all the methods and services available to them?

  • See the problem from another angle, instead of thinking that the problem is the code duplication, we may consider if the problem originates in the lack of policies for code reuse. Recently I read the book Software Engineering with Reusable Components and it indeed has a set of very interesting ideas on how to foster code reusability at the organization level. I will answer in the related question. – edalorzo Apr 1 '14 at 23:49

Some ideas;

  • Clear, well understood, code structure. So that there's an 'obvious' place to put certain code, by folder location or namespaces; if it's a shared extension method for example, then you might find those in a Company.Common.Extensions location. Or set patterns for encapsulation, so that methods should be found inside a relevant type, not externally in "BlobManager" classes. This will help them find existing code if it exists.
  • Unit tests; often devs might feel a method doesn't do exactly what they need, and rather than touch existing code they'll roll their own. Appropriate Unit Tests can aid in a refactor to get existing code changed without breaking current behaviours
  • Code Reviews; maybe awareness is the issue, and a code review helps spread awareness in a team
  • Set expectations in the team that duplication is not appropriate, and enforce that through reviews and refactoring.

The best thing I am aware of is communication. It contains some points:

  • Almost all classes or functions I reused from other programmers inside a project, came to my awareness, because I was talking with them about some issue and therefore knew that they had written something for it. Code reviews and pair programming can reinforce this.
  • Also the code has to talk to you, what I mean is, you need good naming in order to understand if this class or function is useful for you. Therefore, it should perform only one task, have one single responsibility. Forget other documentation, if it is not easy to understand no one dares to use it and again writes his own.
  • The team should agree to place reusable code, a good little developer has created, to some commonly known places everybody can look for it. Even just a simple tools/utilitys-class/file/namespace, is better then to place a helper-function next to the class that only you will ever maintain.

There are a lot of factors. I'll list them roughly in order:

  1. Code Reviews. These should be for 100% of code and should frequently include a senior developer.

  2. Pair Programming. One of the best (though hard) ways to write good code is do pair programming. The challenge is finding a good pair as not all personalities pair well.

  3. Tests. Code code has good tests that acts as documentation on how to use functions and encourage function usage.

  4. Working conditions that encourage discussion, notable an open environment that clusters folks together.

  5. A culture of learning, including lunch-time stuff, books, training, etc.

  6. A culture of software craftmanship with featured refactoring skills and demonstrations of approaches.

  7. Tools that analyze code for quality metrics.