Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question already has an answer here:

Is it a good rule of thumb to always write code for the intent of re-using it somewhere down the road? Or, depending on the size of the component you are writing, is it better practice to design it for re-use when it makes sense with regards to time spent on it. What is a good rule of thumb for spending extra time on analysis and design on project components that have "some probability" of being needed later down the road for other things that may or may need this part.

For example, if I have the need for project X to do things A, and B. A definitely needs to be written for re-use because it just makes sense to do so. B is very project specific at the moment, and I can hack it all together in a couple days to finish the project on time and give everyone kudos for being a great team, etc. Or if we say, lets spend a whole friggin' 2 weeks figuring out what project Y/Z might need this thing for and spend a load of extra time on on part B because someday we might need to use it on project Y/Z (where the savings will be realized).

I'd imagine a perfect world situation would be a nicely crafted combination of project specific vs. re-use architected components given the project. However some code shops might feel it would be a great idea to write everything for the intention of using it at some point down the road.

share|improve this question
    
add comment

marked as duplicate by Joris Timmermans, Jalayn, MichaelT, Martijn Pieters, Dynamic May 16 '13 at 1:24

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

7 Answers

up vote 17 down vote accepted

In my experience, trying to always make everything reusable may lead to over-engineering. However, a certain non-excessive amount of effort to make things reusable is always worth trying to put into things, (when things are amenable to reusability,) because a reusable component is a general purpose component, which means that its interface is abstracted, which means that it is easier to understand it on its own, and figure out how it works and why it works, and what it does and how it does it, when you look at it on its own, or when you look at it 6 months down the road and you don't even remember ever having written it. And these benefits are of course in addition to the fact that it is reusable.

So, to cut a long story short, I believe that the rule of thumb should be: make it reusable if doing so will make its interface and / or its implementation easier to understand.

share|improve this answer
    
Nice one, really well said!! –  Tathagat Verma Jan 11 '13 at 6:18
add comment

What is a good rule of thumb for spending extra time on analysis and design on project components that have "some probability" of being needed later down the road for other things that may or may need this part.

For cases like above my preferences are based on an estimate derived at one of my past projects: re-usable code takes 3-4x times more efforts to write (YMMV).

  • Another thing I noticed is that it's quite hard to properly design code for re-use when all you've got is just one usage example. In other words, when I design "for just in case", without having an example for that, it often turns out that I have to redesign it later when need for real re-use arises.

Given above I tend to avoid designing for re-use until I have a real case for that. In that sense I rather strongly follow YAGNI. On the other hand, when there is at least one case of re-use I try to re/design for that instead of duplicating code - even when my plain calculation of efforts is still in favor of duplication (2x efforts vs 3-4x) - guess this preference have something to do with considerations of further maintenance.


For example, if I have the need for project X to do things A, and B. A definitely needs to be written for re-use because it just makes sense to do so. B is very project specific at the moment, and I can hack it all together in a couple days to finish the project on time and give everyone kudos for being a great team, etc. Or if we say, lets spend a whole friggin' 2 weeks figuring out what project Y/Z might need this thing for and spend a load of extra time on on part B because someday we might need to use it on project Y/Z (where the savings will be realized).

In case like above I'd personally go for quick hacking for B.

The only thing that makes me uncomfortable would be if there are no traces left for this decision (like what is the problem, what options were considered, what was the decision and why). But this is really easy to handle - I do it routinely at decisions like that: just register it in your issue tracker, describe things and let it be there until time allows to take care of that. Or until there's time to prepare that other project Y/Z - when you can include friggin' 2 weeks in the estimate.

  • Issue 1234 - throwaway code in thing B -- fix postponed -- efforts estimate 2 weeks
share|improve this answer
1  
+1 for YAGNI until there is a real re-use scenario. This philosophy hasn't led me astray yet, whereas trying to guess up front about reuse definitely has. –  RationalGeek Jan 12 '12 at 17:53
add comment

The best practice is to write neat and understandable code irrespective of re-use purposes. A good written code can always find it's place in the future. You don't need to specifically write code in a manner which suits re-usage. All you need to do is follow good design principals and a bit of self-documenting code. This will make your code reusable itself.

share|improve this answer
2  
The essential coding practice here is merely to reduce dependencies on other modules or components. Fewer dependencies == more reusable. That's often all that's required. –  S.Lott Dec 27 '11 at 16:40
    
+1; I think we are saying the same thing using different terms. –  Mike Nakis Dec 27 '11 at 17:00
add comment

As you already pointed out, it does come down to balance. In scientific/economics terms, you would evaluate the two sides of your decision, reusable code vs. app-specific hack and sum up the costs and benefits of each side and also take into account any probability values (e.g. the chance the code will actually be needed anywhere else). In reality, we do these calculations subconsciously (using common sense, experience, gut feeling...) almost every day.

Technically, our designs should always be modular and reusable as much as possible, but there are plenty of instance where a "hack" as you put it, will take half a day to write vs. generic component a week. In that case, I would take a stance of the YAGNI principle.

On the other hand, if a) you know there's 80-90% chance the code will be needed again, and it makes sense and b) it doesn't take significantly more time to make it reusable, then I say go ahead and design for reusability... and then for everything else there's the middle gray area :)

Also, in the past I've had success taking the middle ground between your two approaches. I had projects where certain functionality could have been made reusable since day 1, but doing so would have incurred additional costs. So instead, I kept all the code local. In future work when the need for similar functionality arose, I went back to projects where this work was done originally, and at that time paid the extra cost of wrapping those classes into a reusable module. Doing this gives you few advantages: 1) you don't pay extra cost until you need it and 2) later on when you do make a reusable component, you can leverage your knowledge of how well original code worked out in app-specific case and modify its design as needed before introducing it to "the world".

In some cases, original projects were never modified to use the new v2.0 reusable modules because original code already worked and with no active development it made no sense to modify that code. In other cases, once reusable components were tuned and improved, we went back and replaced custom implementations, but only after custom implementations actually required work to be done. So one lesson from all this: even if you "hack" or write custom code, take an hour or two to come up with a clean interface. In the future if you have to modify this code, that interface will make it that much more simpler to remove custom code and replace it with library calls.

share|improve this answer
    
YAGNI only works in the context of code that is constantly, relentlessly refactored. Otherwise it leads to major pain. –  sq33G Dec 27 '11 at 11:41
2  
@sq33G But equally trying to second guess what comes next will bog you down horribly - which is where elements of the agile philosophy come from. I've taken substantially to focusing on solving the problem at hand and worrying about "what if" when it happens - but, as suggested, there are coding styles and practices that will make dealing with change less painful –  Murph Dec 27 '11 at 15:45
add comment

After a while of consciously coding in a generic, dependency-inverted style it really does become effortless. With the bonus of automatically reusable code.

share|improve this answer
1  
"Code that tends to be resuable" rather than "automatically resuable code" but I agree with the basic premise –  Murph Dec 27 '11 at 15:41
add comment

YAGNI. Keep it simple, clear, and well-covered by unit tests.

If it turns out you DO need to re-use it, refactor it as needed. If you have good unit tests in place, the refactoring is fairly low-risk. Besides, in my experience, code that is testable is pretty close to being re-usable anyway. You might need to add in an extension point or two, but if your code is clean to begin with, it shouldn't be a huge deal.

share|improve this answer
add comment

I don't have a rule of thumb in terms of time/effort/cost, but the line I like to use is "reusable code isn't part of a project, it is a project." This is because truly reusable code needs to have its own very well defined set of requirements that take into account everything that's going to be using it and may be using it in the future.

Of course, you can take any given component that's being written as part of a project and make it reusable. But the difference between something that's "reusable" (in quotes) and something that truly does have the potential to be reused is whether or not it can meet the needs of multiple real consumers in all aspects - flexibility, deployment considerations, performance, behavior, configurability, etc. The level of design required to get all that essentially makes a piece of reusable code a project unto itself.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.