Problem
Solution

Problem

When using interfaces, it is important NOT to access the implementation classes (which implement these interfaces) directly.

Here is a simple example of what NOT to do:

   1: public interface LogEntryIF{
   2:      public setUserId( String s );
   3:      public setSessionId( String s );
   4:  }
   5:  
   6: public class LogEntry implements LogEntryIF{
   7:      private String userId, session;
   8:      public setUserId( String s ){ userId = s; }
   9:     public setSessionId( String s ){ sessionId = s; }
  10: }

Don’t do this:

   1: LogEntryIF le = new LogEntry();
   2: le.setUserId( “boo” );
   3: le.setSessionId( “sessionboo” );

So in this simple case, even having the ability to instantiate the LogEntry class is undesirable. There must be a way to instantiate objects of implementation classes:

  • without directly accessing the implemenation classes themselves
  • by relying entirely on the interfaces to access these objects.

Sounds impossible? Not really, by using the Factory pattern it can be done.

Solution

The Factory pattern involves creating a static class which has at least one method to do the following:

  • create an instance of an implementation classes, but return this object reference as the interface.
   1: public interface LogEntryIF{
   2:      public setUserId( String s );
   3:      public setSessionId( String s );
   4: }
   5:  
   6: public class LogEntry implements LogEntryIF{
   7:      private String userId, session;
   8:      public setUserId( String s ){ userId = s; }
   9:      public setSessionId( String s ){ sessionId = s; }
  10: }
  11:  
  12: public class LogFactory{
  13:      public static LogEntryIF getLogEntryInstance(
  14:          String userId ,
  15:          String sessionId ){
  16:          LogEntry le = new LogEntry();
  17:          le.setUserId( userId );
  18:          le.setSessionId( sessionId );
  19:          return le;
  20:      }
  21: }

Usage:

   1: LogEntryIF le = LogFactory.getLogEntryInstance( “boo” , “sessionboo” );

In the solution above, the user does not have to directly access the implementation class (LogEntry) in order to get an instance of it. Also, the factory class returns this instance of the implementation class as an instance of interface.