Realsolve Logo
Blogs
 

Phil Zoio's Weblog, December 31, 2004

Re-usable Code Across Projects

In all the projects I've worked on I've never found it difficult to maximise reuse of code within a project. The problem has always come when I've tried to reuse code across projects. Typically I've found this quite difficult. It can be tempting to cut and paste existing code but I find myself increasingly unwilling to indulge in this. The problem is that you lose a lot of the value of the code. In particular, unit tests which cover the actions don't typically get carried across to the new code base without additional effort. This means that you can expect bugs to appear in the cut and pasted code in unpredictable ways.

The solution to this problem lies in a component-based development approach. I would define a component is a class, or group of classes, which have no within library public method dependencies. A component can be simply lifted out of its current environment and placed in another, without modification.

To build components that are useful and easily reusable, there There are two things you need to do. The first is to minimize the dependencies in your code. The second is the document those dependencies well.

Minimizing Dependencies

Lets consider minimizing dependencies. Dependency analysis is a complex subject whose importance is probably underrated. Any software program will have dependencies. The trick is to minimize the impact on any individual piece of code. Here's the dependency pecking order:

Lets see why I've chosen to prefer external library public methods rather than internal public methods. Public methods in internal libraries are the real villain when it comes to attempting to reuse code across projects. Suppose I have a class which contains some code that needs to be reused.

package com.realsolve.wanttoreusethis;

import com.realsolve.internal1.InternalClassA;
import com.realsolve.internal1.InternalClassB;
import com.realsolve.internal2.*;
import com.realsolve.internal3.*;
import com.realsolve.internal4.*;

/**
 * Some class that I want to reuse externally
 */
public class WantToReuseClass
{
  ... //various useful methods
}

The problem is that as soon as I remove WantToReuseClass from the current library, all of the dependencies defined by InternalClassA and InternalClassB, as well as all the other classes in com.realsolve.internal2 to com.realsolve.internal4 will no longer be satisfied. Dependencies from external libraries will still exist, but they will still be satisfied.

With internal public dependencies, we need to decide whether to maintain the dependency. Maintaining the dependency means migrating the dependency to the new project. This may be undesirable if the class concerned has dependencies of its own, or performs functions which you do not need. Removing the dependency means refactoring the code to no longer use the dependency. If the dependency is not externalized, this is likely to result in code duplication.

This is probably the crux of the problem - it is more expensive and less efficient in terms of developmer productivity to create code that is reusable across projects, unless there is a specific requirement to do this.

So the answer is to find ways to reduce the number of dependencies to internal public classes.

Here are some rules of thumb for doing this:

Documenting Dependencies

I think we need a more formal way of documenting dependencies to facilitate component based development and encourage code reuse across projects. The documentation should be strict enough to compose libraries from components using a tool which understands the metadata, and have a fairly high level of confidence that this code will work first time.

At some stage I'll make a post on how I think this should be done.





Want to comment on this blog? Please email me at philzoio@realsolve.co.uk. At some stage I'll probably add a form, or maybe even a public forum, but for now I'm keeping the site pretty basic.