Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 30: Polymorphism and Java

What to do when switch statements start reappearing in your code

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 2

Anyway, back to the plot!

As Java doesn't have functions or pointers to functions, we can't port the C code to Java. However, Listing 5 demonstrates a mapping from an enumerated type to a function, and Listing 6 shows you how to achieve the same effect in Java.

Listing 6: Improving the design



//everthing else the same as Listing 4. public class Foo implements Traceable { private Hashtable map = new Hashtable(); private class MinimalTrace implements Traceable {/* impl */} private class VerboseTrace implements Traceable {/* impl */} public Foo() { //initialize map map.put( Mode.MIMINAL, new MinimalTrace() ); map.put( Mode.VERBOSE, new VerboseTrace() ); } public void Trace( OutputDevice device, Mode mode) { Traceable t=(Traceable)map.get( mode ); t.Trace( device ); } }


Foo now has innerclasses that implement the different levels of Trace() and uses a Hashtable to map the Mode to the implementation class. To improve the efficiency of the Trace() method, we can introduce a currentMode instance variable with an associated currentImpl to avoid the overhead of the Hashtable.get() method, as shown in Listing 7.

Listing 7: Improving efficiency


public class Foo implements Traceable
{
      private Mode currentMode;
      private Traceable currentImpl;
      private Hashtable map = new Hashtable();
      private class MinimalTrace implements Traceable {/* impl */}
      private class VerboseTrace implements Traceable {/* impl */}
      public Foo()
      {
            //init map as Listing 6
            //assign currentMode and currentImpl to a default
      }
      public void Trace( OutputDevice device, Mode mode )
      {
            if(mode!=currentMode)
            {
                  currentMode=mode;
                  currentImpl=(Traceable)map.get( mode );
            }
            currentImpl.Trace( device );
      }
}


One final area of improvement would be to defer the instantiation of the implementation classes until the classes are required, a technique known as lazy instantiation. I will discuss lazy instantiation in depth in a future article, including how the implications and benefits for Java differ from those for C++.

I will leave it as an exercise for the reader to modify the design of Foo to incorporate lazy instantiation.

About the author

Philip Bishop is technical director and a consultant at Eveque Systems Ltd in the U.K. Eveque Systems specializes in the design and implementation of distributed object systems using Java, CORBA, C++, ODBMS, and so on.
  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (5)
Login
Forgot your account info?

this is actualy good. By Anonymous on October 13, 2009, 11:15 pmthis is actualy good.

Reply | Read entire comment

is it?By Anonymous on October 12, 2009, 9:48 pmwhy?

Reply | Read entire comment

well explained concepts..By Anonymous on September 14, 2009, 9:39 amwell explained concepts..

Reply | Read entire comment

smartBy Anonymous on July 29, 2009, 12:29 pmsmart way of getting rid of switch statement in c++.You use pointers to a functions, comparing it to java, You can use innerclasses which do operations for You.

Reply | Read entire comment

Java BooksBy Anonymous on May 6, 2009, 12:50 amthis is the java book

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources