tl  tr
  Home | Tutorials | Articles | Videos | Products | Tools | Search
Interviews | Open Source | Tag Cloud | Follow Us | Bookmark | Contact   
 Design Patterns > Java Design Patterns > Abstract Factory

Abstract Factory 

Abstract Factory comes under creational design pattern. It provides one more level of abstraction than Factory method. Just as factory methods connects parallel class implementations, Abstract Factory connects parallel factories. It returns one of the available factories based on some condition.

Behaviour & Advantages

  • Instantiates one of the available factories based on some condition.
  • Connects families of related classes or toolkits.
  • Client doesn't need to know the factory implementation class.
  • Abstract factory may auto detect which factory to instantiate or it can also be parameterized just like factory method.
  • The detection logic is implementation dependent.

In this example we have created a DBConnectionFactory which instantiates either OracleConnectionFactory or MySQLConnectionFactory based on some system property. After getting a specific factory, performing other operations is similar irrespective of the implementation.

IConnection interface is shown below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/IConnection.java 
   
package com.bethecoder.tutorials.dp.abstract_factory;

public interface IConnection {
  /**
   * Gets the connection DB vendor name.
   @return
   */
  public String getVendorName();
}
   

IConnectionFactory interface is shown below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/IConnectionFactory.java 
   
package com.bethecoder.tutorials.dp.abstract_factory;

public interface IConnectionFactory {

  /**
   * Get the connection associated with this DB factory.
   
   @return
   */
  public IConnection getConnection();
  
}
   

Here we are expecting a system property DB_CONNECTION_FACTORY to be set with the factory name. The DBConnectionFactory implementation is shown below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/DBConnectionFactory.java 
   
package com.bethecoder.tutorials.dp.abstract_factory;

public class DBConnectionFactory {

  private DBConnectionFactory() {
  }

  public static IConnectionFactory getConnectionFactory() {
    
    String factoryName = System.getProperty("DB_CONNECTION_FACTORY");
    IConnectionFactory connectionFactory = null;
    
    if (factoryName != null) {
      try {
        Class<?> clazz = Class.forName(factoryName);
        connectionFactory = (IConnectionFactoryclazz.newInstance();
      catch (ClassNotFoundException e) {
        e.printStackTrace();
      catch (InstantiationException e) {
        e.printStackTrace();
      catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    else {
      throw new IllegalArgumentException("No system property specified : DB_CONNECTION_FACTORY");
    }
    
    return connectionFactory;
  }
}
   

Oracle family of classes are listed below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/oracle/OracleConnectionFactory.java 
   
package com.bethecoder.tutorials.dp.abstract_factory.oracle;

import com.bethecoder.tutorials.dp.abstract_factory.IConnection;
import com.bethecoder.tutorials.dp.abstract_factory.IConnectionFactory;

public class OracleConnectionFactory implements IConnectionFactory {

  @Override
  public IConnection getConnection() {
    return new OracleConnection();
  }
}
   

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/oracle/OracleConnection.java 
   
package com.bethecoder.tutorials.dp.abstract_factory.oracle;

import com.bethecoder.tutorials.dp.abstract_factory.IConnection;

public class OracleConnection implements IConnection {

  @Override
  public String getVendorName() {
    return "Oracle 11g";
  }
}
   

MySQL family of classes are listed below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/mysql/MySQLConnectionFactory.java 
   
package com.bethecoder.tutorials.dp.abstract_factory.mysql;

import com.bethecoder.tutorials.dp.abstract_factory.IConnection;
import com.bethecoder.tutorials.dp.abstract_factory.IConnectionFactory;

public class MySQLConnectionFactory implements IConnectionFactory {

  @Override
  public IConnection getConnection() {
    return new MySQLConnection();
  }
}
   

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/mysql/MySQLConnection.java 
   
package com.bethecoder.tutorials.dp.abstract_factory.mysql;

import com.bethecoder.tutorials.dp.abstract_factory.IConnection;

public class MySQLConnection implements IConnection {

  @Override
  public String getVendorName() {
    return "MySQL 6.0";
  }
}
   

Abstract Factory usage is shown below,

File Name  :  
com/bethecoder/tutorials/dp/abstract_factory/Test.java 
   
package com.bethecoder.tutorials.dp.abstract_factory;

public class Test {

  /**
   @param args
   */
  public static void main(String[] args) {

    /**
     * Get Connection from OracleConnectionFactory
     */
    System.setProperty("DB_CONNECTION_FACTORY"
        "com.bethecoder.tutorials.dp.abstract_factory.oracle.OracleConnectionFactory");
    
    IConnectionFactory factory = DBConnectionFactory.getConnectionFactory();
    IConnection connection = factory.getConnection();
    System.out.println("Obtained connection for DB Vendor : " + connection.getVendorName());
    
    
    /**
     * Get Connection from MySQLConnectionFactory
     */
    System.setProperty("DB_CONNECTION_FACTORY"
        "com.bethecoder.tutorials.dp.abstract_factory.mysql.MySQLConnectionFactory");
    
    factory = DBConnectionFactory.getConnectionFactory();
    connection = factory.getConnection();
    System.out.println("Obtained connection for DB Vendor : " + connection.getVendorName());
  }

}
   

It gives the following output,
Obtained connection for DB Vendor : Oracle 11g
Obtained connection for DB Vendor : MySQL 6.0



 
  


  
bl  br