Factory Method pattern in Java

In my previous post about the Template Method pattern, I showed how one can leverage lambda expression and default methods. In this post I will explore about factory method pattern and see how one can leverage method references, another feature added in Java 8 alongside lambda expressions.

Lets consider a Vehicle interface and 2 of its implementations namely Car and Vehicle.
 
 
 
 

interface Vehicle{
  public void drive();
  public void clean();
}
class Car implements Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving a car...");
  }

  @Override
  public void clean(){
    System.out.println("Cleaning a car...");
  }
}
class Bus implements Vehicle{
  @Override
  public void drive(){
    System.out.println("Driving a Bus...");
  }

  @Override
  public void clean(){
    System.out.println("Cleaning a Bus...");
  }
}

And to drive() and clean() the Vehicle we would use a VehicleDriver.

Implementation in Java 7 and before

Lets consider the implementation and of VehicleDriver from a Pre Java 8 point of view i.e Java 7 and before.

abstract class VehicleDriver{
  public abstract Vehicle getVehicle();
  public void driveVehicle(){
    getVehicle().drive();
  }
  public void cleanVehicle(){
    getVehicle().clean();
  }
}
class CarDriver extends VehicleDriver{
  @Override
  public Vehicle getVehicle(){
    return new Car();
  }
}

class BusDriver extends VehicleDriver{
  @Override
  public Vehicle getVehicle(){
    return new Bus();
  }
}

In the above VehicleDriver implementation the getVehicle() method is the factory method which is overridden by the CarDriver and Busdriver to return Car and Bus instances respectively. In this way the programmer would be more concerned about using the VehicleDriver abstraction and need not be concerned about its different implementations. There’s another related pattern: Factory Pattern which is slightly different from this pattern and readers should not confuse this with that pattern. Ok, lets quickly look at how this can be used before proceeding to its Java 8 variant:

public class FactoryMethodPattern {
   public static void main(String[] args) {

    handleVehicle(new CarDriver());
    handleVehicle(new BusDriver());
  }
  static void handleVehicle(VehicleDriver2 vDriver){
    System.out.println("Handling a new vehicle. Pre lambda way");
    vDriver.driveVehicle();
    vDriver.cleanVehicle();
  }
}

The output would be:

Handling a new vehicle. Pre lambda way
Driving a car...
Cleaning a car...
Handling a new vehicle. Pre lambda way
Driving a Bus...
Cleaning a Bus...

Leveraging Java 8

Firstly we dont need an abstract VehicleDriver and its 2 different implementation. Instead we make use of Interfaces with Default methods to create the VehicleDriver abstraction as shown below:

interface VehicleDriver{
    public Vehicle getVehicle();
    public default void driveVehicle(){
        getVehicle().drive();
    }
    public default void cleanVehicle(){
        getVehicle().clean();
    }   
}

Now lets come to the interesting part- Using Method references instead of creating different implementation of the VehicleDriver. These method references provide a way for the code to get the required instance of Car or Bus class without going into the hassles of overriding the getVehicle() method. Confused? Curious? Lets look at how we can achieve that:

public class FactoryMethodPatternLambda {
  public static void main(String[] args) {

    handleVehicle(Car::new);
    handleVehicle(Bus::new);
  }
  static void handleVehicle(VehicleDriver vDriver){
    System.out.println("Handling a new vehicle...");
    vDriver.driveVehicle();
    vDriver.cleanVehicle();
  }
}

And the output for this would be:

Handling a new vehicle...
Driving a car...
Cleaning a car...
Handling a new vehicle...
Driving a Bus...
Cleaning a Bus...

We just provided the handleVehicle method a Vehicle to handle and didn’t worry about how its being handled or who’s handling it. But in the Java 7 and before implementation we had to be aware that there is some VehicleDriver abstract class and then we had to override its some method and then create instance of that extended class. My main intention by showing this example is that one can leverage Java 8 features to create cleaner and easy to use APIs. But with all new features comes the learning curve.

Note: In both the above implementations the common part is the Vehicle, Car, Bus classes which are used by both Java 7 and Java 8 implementations.
 

Reference: Factory Method pattern in Java from our JCG partner Mohamed Sanaulla at the Experiences Unlimited blog.
Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

Leave a Reply


6 + = twelve



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books