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

What's a method to do?

How to maximize cohesion while avoiding explosion

  • Print
  • Feedback

Page 2 of 5

// In Source Packet in file: 
//      cohesion/ex1/CoffeeCup.java
// THIS APPROACH WORKS, BUT MAKES THE CODE 
// HARD TO UNDERSTAND AND HARD TO CHANGE
public class CoffeeCup {
    public final static int ADD = 0;
    public final static int RELEASE_SIP = 1;
    public final static int SPILL = 2;
    private int innerCoffee;
    public int modify(int action, int amount) {
        int returnValue = 0;
        switch (action) {
        case ADD:
            // add amount of coffee
            innerCoffee += amount;
            // return zero, even though that is meaningless
            break;
        case RELEASE_SIP:
            // remove the amount of coffee passed as amount
            int sip = amount;
            if (innerCoffee < amount) {
                sip = innerCoffee;
            }
            innerCoffee -= sip;
            // return removed amount
            returnValue = sip;
            break;
        case SPILL:
            // set innerCoffee to 0
            // ignore parameter amount
            int all = innerCoffee;
            innerCoffee = 0;
            // return all coffee
            returnValue = all;
        default:
            // Here should throw an exception, because they
            // passed an invalid command down in action
            break;
        }
        return returnValue;
    }
}


CoffeeCup's modify() method is not very cohesive because it includes code to do tasks that, conceptually, are quite different. Yes, it is a useful method. It can add, sip, and spill, but it can also perplex, befuddle, and confuse. This method is difficult to understand partly because its name, modify(), isn't very specific. If you tried to make the name more specific, however, you would end up with something like addOrSipOrSpill(), which isn't much clearer.

Another reason modify() is hard to understand is that some of the data passed to it or returned from it is used only in certain cases. For example, if the action parameter is equal to CoffeeCup.ADD, the value returned by the method is meaningless. If action equals CoffeeCup.SPILL, the amount input parameter is not used by the method. If you look only at the method's signature and return type, it is not obvious how to use the method.

Figure 1: Passing control down to modify().



See Figure 1 for a graphical depiction of this kind of method. In this figure, the circle for the action parameter is solid black. The blackened circle indicates that the parameter contains data that is used for control. You can differentiate data that is used for control from data that isn't by looking at how a method uses each piece of input data. Methods process input data and generate output data. When a method uses a piece of input data not for processing, but for deciding how to process, that input data is used for control.

To maximize cohesion, you should avoid passing control down into methods. Instead, try to divide the method's functionality among multiple methods that don't require passing down control. In the process, you'll likely end up with methods that have a higher degree of cohesion.

By the way, it is fine to pass data used for control back up from a method. (Throwing an exception is a good example of passing control up.) In general, up is the direction control should go: Data used for control should be passed from a method back to the method that invoked it.

  • Print
  • Feedback

Resources
  • Source packet that contains the example code used in this article http://www.artima.com/flexiblejava/cohesion.html
  • Recommended books on Java Design http://www.artima.com/designtechniques/booklist.html
  • The discussion forum devoted to the material presented in this article. http://www.artima.com/flexiblejava/fjf/cohesion/index.html
  • Object Orientation FAQ http://www.cyberdyne-object-sys.com/oofaq/
  • 7237 Links on Object Orientation http://www.rhein-neckar.de/~cetus/software.html
  • The Object-Oriented Page http://www.well.com/user/ritchie/oo.html
  • Collection of information on OO approach http://arkhp1.kek.jp:80/managers/computing/activities/OO_CollectInfor/OO_CollectInfo.html
  • Design Patterns Home Page http://hillside.net/patterns/patterns.html
  • A Comparison of OOA and OOD Methods http://www.iconcomp.com/papers/comp/comp_1.html
  • Object-Oriented Analysis and Design MethodsA Comparative Review http://wwwis.cs.utwente.nl:8080/dmrg/OODOC/oodoc/oo.html
  • Patterns discussion FAQ http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html
  • Implementing Basic Design Patterns in Java (Doug Lea) http://g.oswego.edu/dl/pats/ifc.html
  • Patterns in Java AWT http://mordor.cs.hut.fi/tik-76.278/group6/awtpat.html
  • Software Technology's Design Patterns Page http://www.sw-technologies.com/dpattern/
  • Synchronization of Java Threads Using Rendezvous http://www-cad.eecs.berkeley.edu/~jimy/classes/rendezvous/
  • Design PatternsElements of Reusable Object-Oriented Software, In Java http://www.zeh.com/local/jfd/dp/design_patterns.html
  • Another example of obvious content from Bill Venners http://www.artima.com/bv/music/obvioussong.html