Well, this quite depends on the language you'll be using in order to support the idea of the design. I'll portray the idea in Java, let's start.
You have the following:
AbstractFacotry instance1 = new ConcreteFacotry1();
AbstractFacotry instance2 = new ConcreteFacotry2();
You want to avoid having to put ConcretFactory#. That's why you'll use a Factory class that is in charge of giving you the correct ConcretFactory# instance based on a parameter (in your case, that database record you mentioned). I'll try to be as brief yet explaining as possible, hope I don't lose anybody in the process.
I'll start with the creation of the abstract class AbstractFactory and concrete classes that extend from it for the purpose of the example.
public abstract class AbstractFactory {}
Of course yours will be much more detailed, I just need it instantiated to run a couple of tests. Now let's great the classes that extend from it:
public class ConcreteFactory1 extends AbstractFactory {}
I won't paste the code for the other ones, they are all the same. Here are the classes I created: ConcreteFactory1, ConcreteFactory2, ConcreteFactory3, ConcreteFactory4.
Next is the class that is in charge of giving you the concrete instance of AbstractFactory based on your database parameter. This implementation assumes that there wont' be more than 15 or so database parameters. And also that said database parameter can be translated into a String.
public class FactoryInstantiator {
public AbstractFactory optionOne(){
return new ConcreteFactory1();
}
public AbstractFactory optionTwo(){
return new ConcreteFactory2();
}
public AbstractFactory optionThree(){
return new ConcreteFactory3();
}
public AbstractFactory optionFour(){
return new ConcreteFactory4();
}
}
Obviously the name option# is the String translation of your database parameter.
The last thing, is to create the class that is in charge of calling the correct method based on the database parameter. Here is where the juice lies, and where you avoid your if-elses and your switches. This is the class you'll be calling from the client.
public class FactoryHandler {
public AbstractFactory getInstance(String databaseParameter) {
try {
return getConcreteInstance(FactoryInstantiator.class, databaseParameter);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException | NoSuchMethodException ex) {
Logger.getLogger(FactoryHandler.class.getName()).log(Level.SEVERE, null, ex);
}
throw new RuntimeException("Could not determine concrete instance based on data base parameter");
}
private AbstractFactory getConcreteInstance(Class<FactoryInstantiator> factoryInstantiator, String databaseParameter)
throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException {
Class[] methodParameterTypes=null;
Object instance = factoryInstantiator.newInstance();
Method method = factoryInstantiator.getDeclaredMethod(databaseParameter, methodParameterTypes);
return (AbstractFactory) method.invoke(instance);
}
}
Specifically, you'll be calling the getInstance(...) method to get your concrete instance. This method is in charge of capturing any exceptions that may arise from calling the getConcreteInstance(..). This separation is for readability and clearness.
The real deal is in getConcreteInstance(..) in charge of calling the appropriate method in FactoryInstantiator based on the dbParameter.
Let's get to using this in the main class as follows:
public class Main {
public static void main(String[] args) {
ArrayList<AbstractFactory> factories = new ArrayList<>();
ArrayList<String> dbParameters = getDBparameters();
FactoryHandler factoryHandler = new FactoryHandler();
for(String dbParameter:dbParameters)
factories.add( factoryHandler.getInstance(dbParameter) );
for(AbstractFactory factory : factories)
System.out.println(factory.getClass());
}
private static ArrayList<String> getDBparameters(){
ArrayList<String> dbparameters = new ArrayList<>();
dbparameters.add("optionOne");
dbparameters.add("optionTwo");
dbparameters.add("optionThree");
dbparameters.add("optionFour");
return dbparameters;
}
}
Here is the printout:
class ConcreteFactory1
class ConcreteFactory2
class ConcreteFactory3
class ConcreteFactory4
And there you have it. Hope it helps.