Enterprise application needs flexible way to setup different implementation for customer. For example, we have an algorithm to calculate production scheduler but it will generate with different results base on factory type (i.e. Job shop, floor shop). So we need to link classes during configuration rather than compilation.

Plugin approach
Pluggable implementations based upon environment (properties file)

// In props file: IDGenerator=id.oracle.OracleIDGenerator

public interface IDGenerator {
   public static final IDGenerator instance=
     (IDGenerator) PluginFactory.getPlugin(IDGenerator.class);
   long getNextId();
}
public class OracleIDGenerator implements IDGenerator {
   public long getNextId() {
    // Get id from Oracle sequence
   }
}

public class PluginFactory {
   private static Properties props=new Properties();
   static {
     try {
       String propsFile = System.getProperty("plugins");
       props.load(new FileInputStream(propsFile));
     } catch (Exception ex) {
       throw new ExceptionInInitializerError(ex);
     }
   }

   public static Object(Class iface) {
      String implName=props.getProperty(iface.getName());
      if(implName==null) {
        thrown new RuntimeException("No plugin for: " +
              iface.getName());
      }
      try {
       return Class.forName(implName).newInstance();
      } catch(Exception ex){
         //ignore...
      }
   }
}

// get Id from IDGenerator
long id=IDGenerator.instance.getNextId();

Dependency Injection
Separate assembler wires objects together based upon configuration information. Here is Spring ApplicationContext.xml:

<bean id=”idGenerator” class=”com.myapp.IDGeneratorImpl”>
<property name=”database”>
<value>oracle</value>
</property>
</bean>

<bean id=”customerDAO” class=”com.myapp.CustomerDAOImpl” lazy-init=”true”>
<property name=”IDGenerator”><ref local=”idGenerator”/></property>
</bean>

Advertisements