Skip to main content

Factory Design Pattern using Reflection

Here I have given an implementation of Factory design pattern in Java using reflection.Please refer to the below link for a quick presentation about Java Refection APIs.

www.cs.washington.edu/education/courses/.../reflection.ppt

I am creating a DB factory which will create an instance of Database manager objects depends on the argument which is passed. Assume that we have an application running in 2 different environment where one environment uses Oracle as a database and another uses Solaris as a database.Upon initialization of the program we have to create a DB manager instance which should return Oracle or Solaris DB manager for the program.

Here I have used reflection to avoid modification to the Factory class if we need to support a new data base tomorrow.

I have factory class as below, DBFactory.java

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;


public class DBFactory {

    private static HashMap m_RegisteredDatabases = new HashMap();

    public static void registerProduct (String id, Class<?> dbclass)
    {
        m_RegisteredDatabases.put(id, dbclass);
    }
    
    public static DBmanager createDBmanager(String id) throws Exception, NoSuchMethodException
    {
        Class dbclass = (Class) m_RegisteredDatabases.get(id);
        Method m = dbclass.getMethod("getInstance", null);
        DBmanager mgr = (DBmanager) m.invoke(null, null);
        return mgr;
        
    }
}

here a hashmap is used tyo maintain the list of registered databases as you see and createDBManager() method uses reflection to call getInstance() method of corresponding class. This avoids modifications to DBFactory.java if a new database is introduced.

An interface is created DBmanager.java
public interface DBmanager {
    
    public void execute();
    
}

Two concrete classes OracleDBmanager.java and SolarisDBmanager.java as below


public class OracleDBmanager implements DBmanager {
    private static DBmanager instance;    
    public static DBmanager getInstance()
    {
        if ( instance == null)
        {
            synchronized (OracleDBmanager.class )
            {
                if ( instance == null)
                {
                    instance = new OracleDBmanager();
                }
            }
        }
        return instance;
    }
    
    public void execute()
    {
        System.out.println("inside OracleDBmanager execute");
    }
}

public class SolarisDBmanager implements DBmanager {
    private static DBmanager instance;    
    public static DBmanager getInstance()
    {
        if ( instance == null)
        {
            synchronized (SolarisDBmanager.class )
            {
                if ( instance == null)
                {
                    instance = new SolarisDBmanager();
                }
            }
        }
        return instance;
    }
    
    public void execute()
    {
        System.out.println("inside SolarisDBmanager execute");
    }
}

The client side code is shown as below in Reflection.java.

public class Reflection {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        DBFactory.registerProduct("env1", OracleDBmanager.class);
        DBFactory.registerProduct("env2", SolarisDBmanager.class);
        DBmanager instance;
        try {
            instance = DBFactory.createDBmanager("env1");
            instance.execute();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

}

Here you see that we have registered the databases upon startup and depends on the argument to factory method, it will create Oracle or Solaris DB manager instances.

Suppose we need to support SQLserver then we need to have a SQLserverDBmanager as below.

public class SQLserverDBmanager implements DBmanager  {

    private static DBmanager instance;    
    public static DBmanager getInstance()
    {
        if ( instance == null)
        {
            synchronized (OracleDBmanager.class )
            {
                if ( instance == null)
                {
                    instance = new SQLserverDBmanager();
                }
            }
        }
        return instance;
    }
    
    public void execute()
    {
        System.out.println("inside SQLServerDBmanager execute");
    }
}

We only need to modify the client side code in Reflection.java.

public class Reflection {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        
        DBFactory.registerProduct("env1", OracleDBmanager.class);
        DBFactory.registerProduct("env2", SolarisDBmanager.class);
        DBFactory.registerProduct("env3", SQLserverDBmanager.class);
        DBmanager instance;
        try {
            instance = DBFactory.createDBmanager("env3");
            instance.execute();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

This will print "inside SQLServerDBmanager execute" to the console.

Comments

Popular posts from this blog

How to create a minikube single node cluster for learning Kubernetes

In this post I will explain how to setup a minikube single node kubernetes cluster using AWS EC2 instance which would help anyone who is trying to learn kubernetes and also help them to gain practical knowledge in kubernetes by running kubernetes commands, creating kubernetes objects etc. Minikube is a single node kubernetes cluster which means a kubernetes cluster with only one node that is a single VM. Minikube is only used for learning purposes and it is not an alternative for a real kubernetes cluster and should not be used for development and production usage. In this example I have launched an AWS EC2 instance with below configuration where I will install minikube and related tools. AWS EC2 Instance Configuration AMI: Ubuntu Free tier eligible 64 bit Instance type : t2-large ( For me t2-small or t2-micro is giving performance issues due to less memory) Once the EC2 instance is up and running, login to the instance using below command on terminal. If you are using wi...

log4j - How to write log to multiple log files using log4j.properties

In Java applications some times you may need to write your log messages to specific log files with its own specific log properties. If you are using log4j internally then first step that you need to do is to have a proper log4j.properties file. Below example shows 2 log4j appenders which write to 2 different log files, one is a debug log and another one is a reports log. Debug log file can have all log messages and reports log can have log messages specific to reporting on say splunk monitoring. # Root logger option log4j.rootLogger=ALL,STDOUT,debugLog log4j.logger.reportsLogger=INFO,reportsLog log4j.additivity.reportsLogger=false     log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n     # Direct log messages to a log file log4j.appender.debugLog=org.apache.log4j.RollingFileAppen...

Create SNMP Client in JAVA Using SNMP4j

Please follow the below mentioned steps to write a very simple SNMP4J application using Java and eclipse IDE. First you need to download a copy of SNMP4J.jar. You can get it from http://www.snmp4j.org/html/download.html Then you need to decide how you are going to test your application. Check whether you have access to any real network devices like Cisco routers or Juniper routers or whether you are aware of any SNMP agent running on any of your servers.There is nothing to worry if you cannot find one , you can start SNMP agent on your desktop machine as well. Here I am giving an example of how you can use your Windows machine to test your application by starting the SNMP service on the machine. I am using a Windows XP machine and below are the steps needed to start SNMP agent on the machine. 1. Go to Start->Control Panel -> Add or Remove Programs -> Add or Remove Windows Components      Select or Check "Management and Monitoring Tools". ...