Forum Stats

  • 3,733,808 Users
  • 2,246,823 Discussions
  • 7,856,882 Comments

Discussions

Question about Factory Method pattern

Nikita.Mospan
Nikita.Mospan Member Posts: 20
edited June 2016 in New To Java

Hello all.

I started learning Java concepts by a book "Thinking in Java, 4th Edition". In the chapter about Interfaces I did not grasp the idea of the "Factory Method pattern". The pattern is described below :

"An interface is intended to be a gateway to multiple implementations, and a typical way to produce objects that fit the interface is the Factory Method design pattern. Instead of calling a constructor directly, you call a creation method on a factory object which produces an implementation of the interface."

//: interfaces/Factories.java
interface Service {
void method1();
void method2();
} //define interface that works with Classes that implement Service interface
interface ServiceFactory {
Service getService();
} class Implementation1 implements Service {
Implementation1() {}
@Override public void method1() {System.out.println("Implementation1 method1"); }
@Override public void method2() {System.out.println("Implementation1 method2"); }
} class Implementation1Factory implements ServiceFactory {
@Override public Service getService() {
  return new Implementation1();
}
} class Implementation2 implements Service {
Implementation2() {}
@Override public void method1() {System.out.println("Implementation2 method1"); }
@Override public void method2() {System.out.println("Implementation2 method2"); }
} class Implementation2Factory implements ServiceFactory {
@Override public Service getService() {
  return new Implementation2();
}
} public class Factories {
public static void serviceConsumer(ServiceFactory fact) {
  Service s = fact.getService();
  s.method1();
  s.method2();
}

public static void main(String[] args) {
  serviceConsumer(new Implementation1Factory());
  serviceConsumer(new Implementation2Factory());
}
}

The necessity of the Factory classes is explained as

"Without the Factory Method, your code would somewhere have to specify the exact type of Service being created, so that it could call the appropriate constructor."

But it sounds strange for me, because we still specify the exact type of the Factory class (Implementation1Factory, Implementation2Factory). So from the logical perspective I currently see no difference using the following code which looks more concise:

//: interfaces/FactoriesTest.java
interface Service {
void method1();
void method2();
} class Implementation1 implements Service {
Implementation1() {}
@Override public void method1() {System.out.println("Implementation1 method1"); }
@Override public void method2() {System.out.println("Implementation1 method2"); }
} class Implementation2 implements Service {
Implementation2() {}
@Override public void method1() {System.out.println("Implementation2 method1"); }
@Override public void method2() {System.out.println("Implementation2 method2"); }
} public class FactoriesTest {
public static void serviceConsumer(Service s) {
  s.method1();
  s.method2();
}

public static void main(String[] args) {
  serviceConsumer(new Implementation1());
  serviceConsumer(new Implementation2());
}
}/* Output:
Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2
*///:~

Of course, I understand that I miss something, but I can't find out what exactly. I would really appreciate if someone presents an example, where the Factory Method is indeed justified.

Thank you very much in advance.

Nikita.Mospan

Best Answer

  • Unknown
    edited May 2016 Accepted Answer
    It's just that the benefit from using this code:
    
    
    1. public static void main(String[] args) { 
    2.   serviceConsumer(new Implementation1Factory()); 
    3.   serviceConsumer(new Implementation2Factory()); 
    public static void main(String[] args) {
      serviceConsumer(new Implementation1Factory());
      serviceConsumer(new Implementation2Factory());
    }
    
    
    
    versus using this code:
    
    
    1. public static void main(String[] args) { 
    2.   serviceConsumer(new Implementation1()); 
    3.   serviceConsumer(new Implementation2()); 
    public static void main(String[] args) {
      serviceConsumer(new Implementation1());
      serviceConsumer(new Implementation2());
    }
    
    
    was not obvious for me.
    

    The difference is 'not obvious' for that code because THERE IS NO DIFFERENCE for that code.

    That's EXACTLY the same code. All you did was rename the methods. Neither of those is a 'factory'.

    Let's go back to one of the things you first said:

    But it sounds strange for me, because we still specify the exact type of the Factory class (Implementation1Factory, Implementation2Factory). So from the logical perspective I currently see no difference using the following code which looks more concise:
    

    Yes - for both methods you 'specify the exact type' you want.

    The 'difference' in using a pattern is that with the patter the 'exact type' is specified DYNAMICALLY rather than statically.

    So you do NOT hard-code the type instance that you want. You pass parameters that the factory uses to determine which type instance is needed and then the factory method calls you appropriate constructor for the appropriate type.

    Consider this example of 'static' creation using a 'NewService' interface as what is needed

    // static creation of specify instance types
    Service myNewService = new Implementation1();
    Service myOtherNewService = new Implementation2();
    

    Those are STATIC creations because the actual type to create is hardcoded in the NEW statement.

    Now consider this example of dynamic creation (do NOT code like this - this is ONLY an example to illustrate the difference between static and dynamic instantiation)

    // static creation of specify instance types
    
    // dynamic creation
    public static Service NewServiceFactory(int serviceType); // notice the actual type is specified as a parameter
    . . .
    Service myNewService = NewServiceFactory(1);
    Service myOtherNewService = NewServiceFactory(2);
    

    The KEY difference is that for dynamic creation your code does NOT directly specify the type of instance to create. That is delegated to the factory method.

    Your code only provides parameters that 'indirectly' help the factory method determine which type instance to create.

    You would pass a parameter using a number or name of the actual type. The parameters would represent functionality that is needed.

    public static Service NewServiceFactory(String dataSource); // source of data must be either File or Oracle
    . . .
    Service myNewService = NewServiceFactory("File");
    Service myOtherNewService = NewServiceFactory("Oracle");
    

    Based on the parameter the factory method would create an instance of 'NewService' that is appropriate for reading from files or has functionality to get data from an Oracle database.

    As you can imagine the implementations for those two datasources will be TOTALLY different but each will fulfill the same contract for the NewService interfact.

    That factory method allows your code to AVOID hard-coding specify class references and focus instead on providing the info about the functionality that is needed.

    The factory method can then be easily modified to use new instance types or new constructor method signatures with no need to modify your code.

    So let me repeat one of the main tenets for FACTORIES

    The KEY difference is that for dynamic creation your code does NOT directly specify the type of instance to create. That is delegated to the factory method.
    

    A FACTORY, which is a SINGLETON (meaning there is ONLY ONE in your entire app), does ALL creation for that interface type.

Answers

  • Jiri.Machotka-Oracle
    Jiri.Machotka-Oracle Member Posts: 5,078
    edited May 2016

    Take a look at the factory method pattern explained: https://en.wikipedia.org/wiki/Factory_method_pattern

    "that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created."

    Having read the quotation I actually guess that the purpose was to explain the concept of an interface using the factory method pattern. When I learned Java from an earlier edition of Thinking in Java (2000) patterns were not used, and the explanation of interfaces was different.

    Should I explain the concept of interface, I'd use something like this:

    - interfaces is a way to implement multiple inheritance in Java (available in C++); a class can extend (inherit) from a single class (getting its attributes and methods), but a class may implement multiple interfaces

    - unlike 'extend-like' inheritance, an interface (see http://tutorials.jenkov.com/java/interfaces.html) "can only contain method signatures and fields", not "an implementation of the methods" (nor its constructors)

    - therefore, each class implementing the interface will have to implement all the methods with the exact signatures as being prescribed by the interface

    - if you want to instantiate such an object, however, without knowing its exact class/constructors, you might want to call one of the methods prescribed by the interface, e.g. createMe(par1), that will do that for you, usually returning the new object as the method's result.

    This, and nothing else, is IMHO meant by the sentence.

    Nikita.MospanNikita.Mospan
  • TPD-Opitz
    TPD-Opitz Member Posts: 2,465 Silver Trophy
    edited May 2016
    Nikita.Mospan wrote:
    
    Hello all.
    
    I started learning Java concepts by a book "Thinking in Java, 4th Edition". In the chapter about Interfaces I did not grasp the idea of the "Factory Method pattern". The pattern is described below :
     [...]
    The necessity of the Factory classes is explained as
    
    "Without the Factory Method, your code would somewhere have to specify the exact type of Service being created, so that it could call the appropriate constructor."
    
    
    But it sounds strange for me, because we still specify the exact type of the Factory class (Implementation1Factory, Implementation2Factory). So from the logical perspective I currently see no difference using the following code which looks more concise:
    
    
    1. //: interfaces/FactoriesTest.java 
    2. interface Service { 
    3. void method1(); 
    4. void method2(); 
    5. class Implementation1 implements Service { 
    6. Implementation1() {} 
    7. @Override public void method1() {System.out.println("Implementation1 method1"); } 
    8. @Override public void method2() {System.out.println("Implementation1 method2"); } 
    9. class Implementation2 implements Service { 
    10. Implementation2() {} 
    11. @Override public void method1() {System.out.println("Implementation2 method1"); } 
    12. @Override public void method2() {System.out.println("Implementation2 method2"); } 
    13. public class FactoriesTest { 
    14. public static void serviceConsumer(Service s) { 
    15.   s.method1(); 
    16.   s.method2(); 
    17.   
    18. public static void main(String[] args) { 
    19.   serviceConsumer(new Implementation1()); 
    20.   serviceConsumer(new Implementation2()); 
    21. }/* Output:
    22. Implementation1 method1
    23. Implementation1 method2
    24. Implementation2 method1
    25. Implementation2 method2
    26. *///:~ 
    //: interfaces/FactoriesTest.java
    interface Service {
     void method1();
     void method2();
    }
    class Implementation1 implements Service {
     Implementation1() {}
     @Override public void method1() {System.out.println("Implementation1 method1"); }
     @Override public void method2() {System.out.println("Implementation1 method2"); }
    }
    class Implementation2 implements Service {
     Implementation2() {}
     @Override public void method1() {System.out.println("Implementation2 method1"); }
     @Override public void method2() {System.out.println("Implementation2 method2"); }
    }
    public class FactoriesTest {
     public static void serviceConsumer(Service s) {
      s.method1();
      s.method2();
     }
     
     public static void main(String[] args) {
      serviceConsumer(new Implementation1());
      serviceConsumer(new Implementation2());
     }
    }/* Output:
    Implementation1 method1
    Implementation1 method2
    Implementation2 method1
    Implementation2 method2
    *///:~
    
    Of course, I understand that I miss something, but I can't find out what exactly. I would really appreciate if someone presents an example, where the Factory Method is indeed justified.
    

    I think there are some situations:

    First of all when calling a constructor you are not able to return a dummy or default implementation in case the that the Object cannot be created. Our options are to either throw an exception or create an object with an invalid state.

    Also what if the number of (possible) implementations  of the interface is not knows at the time you write your main method?

    What if you want to have different Implementations depending on execution context (e.g. real live versus unit test?)

    OK, this needs a more sophisticated pattern called abstract factory...

    bye

    TPD

    Nikita.Mospan
  • Nikita.Mospan
    Nikita.Mospan Member Posts: 20
    edited May 2016

    Thank you very much for the answers.

    It's just that the benefit from using this code:

    public static void main(String[] args) {
      serviceConsumer(new Implementation1Factory());
      serviceConsumer(new Implementation2Factory());
    }
    
    

    versus using this code:

    public static void main(String[] args) {
      serviceConsumer(new Implementation1());
      serviceConsumer(new Implementation2());
    }
    
    

    was not obvious for me. But your answers gave me the clue that the first approach (with Factory pattern) does make sense if the Factory has some non-trivial logic for creating instances of the class that implements a particular interface, like this for example:

    //: interfaces/Factories1.java
    interface Service {
    void method1();
    void method2();
    } //define interface that works with Classes that implement Service interface
    interface ServiceFactory {
    Service getService(int i);
    } class Implementation1 implements Service {
    Implementation1() {}
    @Override public void method1() {System.out.println("Implementation1 method1"); }
    @Override public void method2() {System.out.println("Implementation1 method2"); }
    } class Implementation1Child extends Implementation1 {
    @Override public void method1() {System.out.println("Implementation1Child method1"); }
    @Override public void method2() {System.out.println("Implementation1Child method2"); }
    } class Implementation1Factory implements ServiceFactory {
    @Override public Service getService(int i) {
      if (i < 1)
       return new Implementation1();
      else
       return new Implementation1Child();
    }
    } public class Factories1 {
    public static void serviceConsumer(ServiceFactory fact, int i) {
      Service s = fact.getService(i);
      s.method1();
      s.method2();
    }

    public static void main(String[] args) {
      serviceConsumer(new Implementation1Factory(), 0);  //Implementation1 methods will be called
      serviceConsumer(new Implementation1Factory(), 1);  //Implementation1Child methods will be called
    }
    }/* Output:
    Implementation1 method1
    Implementation1 method2
    Implementation1Child method1
    Implementation1Child method2
    *///:~

    So here, the pattern allows us to use single Factory constructor, but produce different objects with different implementations of the interface. Am I correct that in such situations this pattern is suitable?

    Thank you.

  • Jiri.Machotka-Oracle
    Jiri.Machotka-Oracle Member Posts: 5,078
    edited May 2016

    Yes.

    But the same time these different objects (or more precisely, instantiations of different classes) will have the same attributes and methods with same signatures, so you may use these without paying attention to the exact class implementing the interface.

  • Unknown
    edited May 2016 Accepted Answer
    It's just that the benefit from using this code:
    
    
    1. public static void main(String[] args) { 
    2.   serviceConsumer(new Implementation1Factory()); 
    3.   serviceConsumer(new Implementation2Factory()); 
    public static void main(String[] args) {
      serviceConsumer(new Implementation1Factory());
      serviceConsumer(new Implementation2Factory());
    }
    
    
    
    versus using this code:
    
    
    1. public static void main(String[] args) { 
    2.   serviceConsumer(new Implementation1()); 
    3.   serviceConsumer(new Implementation2()); 
    public static void main(String[] args) {
      serviceConsumer(new Implementation1());
      serviceConsumer(new Implementation2());
    }
    
    
    was not obvious for me.
    

    The difference is 'not obvious' for that code because THERE IS NO DIFFERENCE for that code.

    That's EXACTLY the same code. All you did was rename the methods. Neither of those is a 'factory'.

    Let's go back to one of the things you first said:

    But it sounds strange for me, because we still specify the exact type of the Factory class (Implementation1Factory, Implementation2Factory). So from the logical perspective I currently see no difference using the following code which looks more concise:
    

    Yes - for both methods you 'specify the exact type' you want.

    The 'difference' in using a pattern is that with the patter the 'exact type' is specified DYNAMICALLY rather than statically.

    So you do NOT hard-code the type instance that you want. You pass parameters that the factory uses to determine which type instance is needed and then the factory method calls you appropriate constructor for the appropriate type.

    Consider this example of 'static' creation using a 'NewService' interface as what is needed

    // static creation of specify instance types
    Service myNewService = new Implementation1();
    Service myOtherNewService = new Implementation2();
    

    Those are STATIC creations because the actual type to create is hardcoded in the NEW statement.

    Now consider this example of dynamic creation (do NOT code like this - this is ONLY an example to illustrate the difference between static and dynamic instantiation)

    // static creation of specify instance types
    
    // dynamic creation
    public static Service NewServiceFactory(int serviceType); // notice the actual type is specified as a parameter
    . . .
    Service myNewService = NewServiceFactory(1);
    Service myOtherNewService = NewServiceFactory(2);
    

    The KEY difference is that for dynamic creation your code does NOT directly specify the type of instance to create. That is delegated to the factory method.

    Your code only provides parameters that 'indirectly' help the factory method determine which type instance to create.

    You would pass a parameter using a number or name of the actual type. The parameters would represent functionality that is needed.

    public static Service NewServiceFactory(String dataSource); // source of data must be either File or Oracle
    . . .
    Service myNewService = NewServiceFactory("File");
    Service myOtherNewService = NewServiceFactory("Oracle");
    

    Based on the parameter the factory method would create an instance of 'NewService' that is appropriate for reading from files or has functionality to get data from an Oracle database.

    As you can imagine the implementations for those two datasources will be TOTALLY different but each will fulfill the same contract for the NewService interfact.

    That factory method allows your code to AVOID hard-coding specify class references and focus instead on providing the info about the functionality that is needed.

    The factory method can then be easily modified to use new instance types or new constructor method signatures with no need to modify your code.

    So let me repeat one of the main tenets for FACTORIES

    The KEY difference is that for dynamic creation your code does NOT directly specify the type of instance to create. That is delegated to the factory method.
    

    A FACTORY, which is a SINGLETON (meaning there is ONLY ONE in your entire app), does ALL creation for that interface type.

  • Nikita.Mospan
    Nikita.Mospan Member Posts: 20
    edited May 2016

    Thank you, topic is closed.

  • Nikita.Mospan
    Nikita.Mospan Member Posts: 20
    edited May 2016

    I rewrote example to illustrate the statement from the last explanation:

    You pass parameters that the factory uses to determine which type instance is needed and then the factory method calls you appropriate constructor for the appropriate type.
    
    //: interfaces/Factories1.java
    interface Service {
    void method1();
    void method2();
    } //define interface that works with Classes that implement Service interface
    interface ServiceFactory {
    Service getService();
    } class Implementation1 implements Service {
    Implementation1() {}
    @Override public void method1() {System.out.println("Implementation1 method1"); }
    @Override public void method2() {System.out.println("Implementation1 method2"); }
    } class Implementation1Child extends Implementation1 {
    @Override public void method1() {System.out.println("Implementation1Child method1"); }
    @Override public void method2() {System.out.println("Implementation1Child method2"); }
    } class Implementation1Factory implements ServiceFactory {
    private int i;

    Implementation1Factory (int i) {this.i = i; }

    @Override public Service getService() {
      if (i < 1)
       return new Implementation1();
      else
       return new Implementation1Child();
    }
    } public class Factories1 {
    public static void serviceConsumer(ServiceFactory fact) {
      Service s = fact.getService();
      s.method1();
      s.method2();
    }

    public static void main(String[] args) {
      serviceConsumer(new Implementation1Factory(0));  //Implementation1 methods will be called
      serviceConsumer(new Implementation1Factory(1));  //Implementation1Child methods will be called
    }
    }/* Output:
    Implementation1 method1
    Implementation1 method2
    Implementation1Child method1
    Implementation1Child method2
    *///:~

    Now I got it.

  • Unknown
    edited May 2016
    Nikita.Mospan wrote:
    
    Now I got it.
    

    Now that you 'got it' - notice that YOUR code doesn't EVER directly know (or care) what the actual class is that the factory produced.

    Such isolation (another term is 'loose coupling') is another MAJOR feature of using factories.

    It let's you use ANY library (jar file, etc) that has classes that support the interface. A common method of doing that is to register classes that can support specific interfaces along with the parameters they take.

    Then the factory method can actually query the registered classes to get one that meets the requirements. Use a different library and you will get a a DIFFERENT implementation class.

    Can you now guess how useful that can be in writing code? It means that your initial implementation can be a simple, brute force, poorly performing implementation that gets the job done.

    Then when your entire app is written you can perform tests and replace any poorly performing parts with more efficient class implementations - WITHOUT CHANGING YOUR CORE CODE!

    Reread that last paragraph. Factory patterns make modular programming MUCH easier since it allows 'plug-and-play' for functional pieces.

    That is the strength of using the factory pattern. It isolates your code from even caring about the actual implementation classes.

    Try writing some simple, sample code to test what I just said above.

    Write a factory class/method that returns an instance of a Collection interface:

    https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html

    All Known Implementing Classes:
        AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList,
        AbstractSet, ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList,
        BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedDeque,
        ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList,
        CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons,
        LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList,
        LinkedTransferQueue, PriorityBlockingQueue, PriorityQueue, RoleList,
        RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector
    

    As the API doc above shows all of those classes implement that same interface.

    So modify the sample code you posted to pass ONE parameter to a factory method that specifies which one of those concrete classes to instantiate and return.

    For example

    public static Collection myCollectionFactory(String collectionType) where 'collectionType' is either 'Vector' or 'ArrayList'.

    If the parameter is 'Vector' create an instance of Vector and return it. Same for 'ArrayList'.

    Then note how your own sample code doesn't even know or care what the actual underlying type is. It can just use it by making calls on the methods of the Collection interface.

  • Nikita.Mospan
    Nikita.Mospan Member Posts: 20
    edited May 2016
    So modify the sample code you posted to pass ONE parameter to a factory method that specifies which one of those concrete classes to instantiate and return.
    
    

    Have I understood you correctly? (please have a look at the code below)

    //: interfaces/Factories1.java
    interface Service {
    void method1();
    void method2();
    } interface ServiceFactory {
    Service getService();
    String getClassName();
    } class Implementation1 implements Service {
    Implementation1() {}
    @Override public void method1() {System.out.println("Implementation1 method1"); }
    @Override public void method2() {System.out.println("Implementation1 method2"); }
    } class Implementation2 implements Service { Implementation2() {}
    @Override public void method1() {System.out.println("Implementation2 method1"); }
    @Override public void method2() {System.out.println("Implementation2 method2"); }
    } class ImplementationFactory implements ServiceFactory {
    private String className;

    ImplementationFactory (String className) {this.className = className; }

    @Override public String getClassName() { return className; }

    @Override public Service getService() {
      try{
       return (Service) Class.forName(className).newInstance();
      }catch (InstantiationException x) {
       x.printStackTrace();
       return null;
      } catch (IllegalAccessException x) {
       x.printStackTrace();
       return null;
      } catch (ClassNotFoundException x) {
       x.printStackTrace();
       return null;
      }  
    }
    } public class Factories1 {
    public static void serviceConsumer(ServiceFactory fact) {
      Service s = fact.getService();
      if (s != null) {
       s.method1();
       s.method2();
      } else {
       System.out.println("Exception occured while trying to create instance of class: " + fact.getClassName());
      }
    }

    public static void main(String[] args) {
      serviceConsumer(new ImplementationFactory("Implementation1"));  //Implementation1 methods will be called
      serviceConsumer(new ImplementationFactory("Implementation2"));  //Implementation2 methods will be called
      serviceConsumer(new ImplementationFactory("Implementation3"));  //Will generate ClassNotFoundException
    }
    }/* Output:
    Implementation1 method1
    Implementation1 method2
    Implementation2 method1
    Implementation2 method2
    java.lang.ClassNotFoundException: Implementation3
            at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
            at java.lang.Class.forName0(Native Method)
            at java.lang.Class.forName(Class.java:264)
            at ImplementationFactory.getService(Factories1.java:34)
            at Factories1.serviceConsumer(Factories1.java:50)
            at Factories1.main(Factories1.java:62)
    Exception occured while trying to create instance of class: Implementation3
    *///:~

    Thanks.

  • Unknown
    edited May 2016
    Have I understood you correctly?
    

    You tell me! Is there ANYTHING in that code that even remotely resembles what I said?

    public static Collection myCollectionFactory(String collectionType) where 'collectionType' is either 'Vector' or 'ArrayList'.
    

    Reread what I last posted.

  • 2714510
    2714510 Member Posts: 7
    edited June 2016

    Hello Nikita

    I am facing same issue in OBIEE action link as you have posted in below post

    Web Service example using Action Link in OBIEE 11.1.1.7 does not work

    Did you get solution for this?

This discussion has been closed.