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

Designing fields and methods

How to keep fields focused and methods decoupled

  • Print
  • Feedback

Page 4 of 5

// In source packet in file coupling/ex3/Example3.java
class Example3 {
    public static void main(String[] args) {
        CoffeeCup cup = new CoffeeCup();
        Liquid.convertOzToMl(16, cup);
        //...
    }
}


The problem here is that convertOzToMl() is now coupled to the CoffeeCup class. This is less flexible than the first version of convertOzToMl(), which returned the milliliters as an int. If later, someone wanted to convert ounces to milliliters for some purpose that didn't involve a coffee cup, they would have to rewrite the method, write a different method, or create a CoffeeCup object just to hold the output.

In Figure 3 you can see a graphical depiction of this kind of method.

Figure 3. A bad utility method

A truly ugly utility method
The worst way to write the convertOzToMl() method (the way that yields the maximum coupling) is to take an input from a public static variable and put the output in another public static variable. A public static (but not final) variable in Java is equivalent in functionality and danger to global variables of C or C++. Here's an example:

// In source packet in file coupling/ex4/Liquid.java
// THIS APPROACH WORKS, BUT MAKES THE CODE HARD TO UNDERSTAND
// AND HARD TO CHANGE
class Liquid {
    private static final double FL_OUNCES_PER_ML = 12.0/355.0;
    private static final double ML_PER_FL_OUNCE = 355.0/12.0;
    /**
    * Converts fluid ounces to milliliters
    */
    public static void convertOzToMl() {
        double d = PurpleZebra.k * ML_PER_FL_OUNCE;
        d += 0.5;
        FlyingSaucer.q = (int) d;
    }
}
// In source packet in file coupling/ex4/FlyingSaucer.java
class FlyingSaucer {
    public static int q;
    //...
}
// In source packet in file coupling/ex4/PurpleZebra.java
class PurpleZebra {
    public static int k;
    //...
}


To use the above version of convertOzToMl(), a programmer would have to do the following:

// In source packet in file coupling/ex4/Example4.java
class Example4 {
    public static void main(String[] args) {
        PurpleZebra.k = 16;
        Liquid.convertOzToMl();
        int mlFor16Oz = FlyingSaucer.q;
        System.out.println("Ml for 16 oz is: " + mlFor16Oz);
    }
}


To use this version of convertOzToMl(), client programmers would have to know a lot about the internal implementation of the method. They would have to know they must put their ounces into the static variable PurpleZebra.k and grab the milliliters out of FlyingSaucer.q. By contrast, the "good" version of convertOzToMl() shown earlier in this article enabled programmers to understand how to use it simply by looking at the method's signature and return type. This "ugly" version, because its signature and return type don't reveal all its inputs and outputs, is harder to understand than the good version.

What's more, someone working on FlyingSaucer, not realizing that q was being used elsewhere, might delete the variable or use it for some other purpose. If q does get used for some other purpose and the program is multithreaded, the value of q could get trampled by a different thread after it is assigned the ounces but before convertOzToMl() gets a chance to use it.

  • Print
  • Feedback

Resources
  • The Heisenberg Uncertainty Principle states that we can't know both the position and the momentum of elementary particles, because the act of measuring one of these values changes the other. Put another way, if elementary particles were objects, they wouldn't have any state-view methods, because you couldn't determine their state (in this case, position and momentum) without changing that state.
  • Recommended books on Java Design http://www.artima.com/designtechniques/booklist.html
  • Source packet that contains the example code used in this article http://www.artima.com/flexiblejava/coupling.html
  • The discussion forum devoted to the material presented in this article. http://www.artima.com/flexiblejava/fjf/fieldsmethods/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