Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 107: Maximize your code reusability

Overcome deficiencies in the traditional OOP approach to reuse

  • Print
  • Feedback
That reuse is a myth seems to be an increasingly common sentiment among programmers. Perhaps, however, reuse is difficult to achieve because deficiencies exist in the traditional object-oriented programming approach to reuse. This tip describes three steps that form a different approach to enabling reuse.

Step 1: Move functionality out of class instance methods

Class inheritance is a suboptimal mechanism for code reuse due to its lack of precision. Namely, you cannot reuse a single method of a class without inheriting that class's other methods as well as its data members. That excess baggage needlessly complicates the code wishing to reuse the method. The dependency of an inheriting class on its parent introduces additional complexity: changes made to the parent class can break the subclass; when modifying either class, it can be difficult to remember which methods are or are not overridden; and, it can be unclear whether or not an overridden method should call the corresponding parent method.

Any method that performs a single conceptual task should be able to stand on its own as a first-class candidate for reuse. To achieve that, we must revert back to procedural programming by moving code out of class instance methods and into globally visible procedures. To promote the reuse of such procedures, you should code them just like static utility methods: each procedure should use only its input parameters and/or calls to other globally visible procedures to do its job, and should make no use of any nonlocal variables. That reduction in external dependencies decreases the complexity of using the procedure, thereby increasing the motivation for reusing it elsewhere. Of course, even code that is not intended for reuse benefits from that organization, as its structure invariably becomes far cleaner.

In Java, methods cannot stand on their own outside of a class. Instead, you can take related procedures and make them publicly visible static methods of a single class. As an example, you could take a class that looks something like this:

class Polygon {
      .
      .
      public int getPerimeter() {...}
      public boolean isConvex() {...}
      public boolean containsPoint(Point p) {...}
      .
      .
}


and change it to look something like this:

class Polygon {
      .
      .
      public int getPerimeter() {return pPolygon.computePerimeter(this);}
      public boolean isConvex() {return pPolygon.isConvex(this);}
      public boolean containsPoint(Point p) {return pPolygon.containsPoint(this, p);}
      .
      .
}


Here, pPolygon would be this:

class pPolygon {
    static public int computePerimeter(Polygon polygon) {...}
    static public boolean isConvex(Polygon polygon) {...}
    static public boolean containsPoint(Polygon polygon, Point p) {...}
}


The class name pPolygon reflects that the procedures enclosed by the class are most concerned with objects of type Polygon. The p in front of the name denotes that the class's only purpose is to group publicly visible static procedures. While it is nonstandard in Java to have a class name start with a lowercase letter, a class such as pPolygon does not perform the normal class function. That is, it does not represent a class of objects; it is rather just an organizational entity required by the language.

  • Print
  • Feedback

Resources