views:

1478

answers:

11

Any code can be reused in a way or an other, at least if you modify the code. Random code is not very reusable as such. When I read some books, they usually say that you should explicitly make the code reusable by taking into account other situations of code usage too. But certain code should not be an omnipotent all doing class either.

I would like to have reusable code that I don't have to change later. How do you make code reusable? What are the requirements for code being reusable? What are the things that reusable code should definitely have and what things are optional?

+14  A: 

See 10 tips on writing reusable code for some help.

  1. Keep the code DRY. Dry means Don't repeat yourself.
  2. Make a class/method do just one thing.
  3. Write unit tests for your classes AND make it easy to test classes.
  4. Remove the business logic or main code away from any framework code
  5. Try to think more abstractly and use Interfaces and Abstract classes.
  6. Code for extension. Write code that can easily be extended in the future.
  7. Don't write code that isn't needed.
  8. Try to reduce coupling.
  9. Be more Modular
  10. Write code like your code is an External API
Galwegian
This concentrates on tactics. But tactics without a good strategy is just motion without progress. First you need to create a solid plan for reuse, and then sell that plan to senior management.
RoadWarrior
+4  A: 

If you take the TDD approach, then your code only becomes re-usable as your refactor based on forthcoming scenarios.

Personally I find constantly refactoring produces cleaner code than trying to second-guess what scenarios I need to code a particular class for.

Duncan
+1  A: 

You'll write various modules (parts) when writing a relatively big project. Reusable code in practice means you'll have create libraries that other projects needing that same functionality can use.

So, you have to identify modules that can be reused, for that

  1. Identify the core competence of each module. For instance, if your project has to compress files, you'll have a module that will handle file compression. Do NOT make it do more than ONE THING. One thing only.

  2. Write a library (or class) that will handle file compression, without needing anything more than the file to be compressed, the output and the compression format. This will decouple the module from the rest of the project, enabling it to be (re)used in a different setting.

  3. You don't have to get it perfect the first time, when you actually reuse the library you will probably find out flaws in the design (for instance, you didn't make it modular enough to be able to add new compression formats easily) and you can fix them the second time around and improve the reusability of your module. The more you reuse it (and fix the flaws), the easier it'll become to reuse.

The most important thing to consider is decoupling, if you write tightly coupled code reusability is the first casualty.

Leave all the needed state or context outside the library. Add methods to specify the state to the library.

Vinko Vrsalovic
I like the idea of library. It is then clear, when the reusable code is in the library.
Silvercode
A: 

To add to the above mentioned items, I'd say:

  • Make those functions generic which you need to reuse
  • Use configuration files and make the code use the properties defined in files/db
  • Clearly factor your code into such functions/classes that those provide independent functionality and can be used in different scenarios and define those scenarios using the config files
Salman Kasbati
A: 

I would add the concept of "Class composition over class inheritance" (which is derived from other answers here). That way the "composed" object doesn't care about the internal structure of the object it depends on - only its behavior, which leads to better encapsulation and easier maintainability (testing, less details to care about). In languages such as C# and Java it is often crucial since there is no multiple inheritance so it helps avoiding inheritance graph hell u might have.

reshefm
+2  A: 

More than anything else, maintainability makes code reusable.

Reusability is rarely a worthwhile goal in itself. Rather, it is a by-product of writing code that is well structured, easily maintainable and useful.

If you set out to make reusable code, you often find yourself trying to take into account requirements for behaviour that might be required in future projects. No matter how good you become at this, you'll find that you get these future-proofing requirements wrong.

On the other hand, if you start with the bare requirements of the current project, you will find that your code can be clean and tight and elegant. When you're working on another project that needs similar functionality, you will naturally adapt your original code.

I suggest looking at the best-practices for your chosen programming language / paradigm (eg. Patterns for Java / C# types), the Lean / Agile programming literature, and (of course) the book "Code Complete". Understanding the advantages and disadvantages of these approaches will improve your coding practice no end. All your code will then become reausable - but 'by accident', rather than by design.

Also, see here: Writing Maintainable Code

Kramii
A: 

As mentioned, modular code is more reusable than non-modular code.

One way to help towards modular code is to use encapsulation, see encapsulation theory here: http://www.edmundkirwan.com/

Ed.

A: 

Object-orientation allows you to refactor code into superclasses. This is perhaps the easiest, cheapest and most effective kind of reuse. Ordinary class inheritance doesn't require a lot of thinking about "other situations"; you don't have to build "omnipotent" code.

Beyond simple inheritance, reuse is something you find more than you invent. You find reuse situations when you want to reuse one of your own packages to solve a slightly different problem. When you want to reuse a package that doesn't precisely fit the new situation, you have two choices.

  1. Copy it and fix it. You now have to nearly similar packages -- a costly mistake.

  2. Make the original package reusable in two situations.

Just do that for reuse. Nothing more. Too much thinking about "potential" reuse and undefined "other situations" can become a waste of time.

S.Lott
+2  A: 

For most definitions of "reuse", reuse of code is a myth, at least in my experience. Can you tell I have some scars from this? :-)

By reuse, I don't mean taking existing source files and beating them into submission until a new component or service arrives. I mean taking a specific component or service and reusing it without alteration.

I think the first step is to get yourself into a mindset that it's going to take at least 3 iterations to create a reusable component. Why 3? Because the first time you try to reuse a component, you always discover something that it can't handle. So then you have to change it. This happens a couple of times, until finally you have a component that at least appears to be reusable.

The other approach is to do an expensive forward-looking design. But then the cost is all up-front, and the benefits (may) appear some time down the road. If your boss insists that the current project schedule always dominates, then this approach won't work.

RoadWarrior
A: 

Others have mentioned these tactics, but here they are formally. These three will get you very far:

bzlm
A: 

Avoid reinventing the wheel. That's it. And that by itself has many benefits mentioned above. If you do need to change something, then you just create another piece of code, another class, another constant, library, etc... it helps you and the rest of the developers working in the same application.

Ricardo