Implementing Strategy pattern with Reflection
I'm trying to implement the strategy pattern using reflection, i.e. instantiate a new Concrete Strategy object using it's class name.
I want to have a configurable file with the class name in it. We have a database manager that will make changes available during run-time. Here's what I have so far:
StrategyInterface intrf = null;
try {
String className = (String)table.get(someId);
intrf = (StrategyInterface) Class.forName(className).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
return intrf;
I hav开发者_如何学Pythone a Class ConcreteStrategy
which implements StrategyInterface
. I have a test running in whcih table.get(someID)
returns the String "ConcreteStrategy"
.
My problem is that ClassNotFoundEception
is thrown. Why is this happening, and how I could get ConcreteStrategy
to be instantiated given a class name? I don't want to use an if-else
block because number of concrete strategy objects will increase with time and development.
EDIT: I fixed it the following way,
String className = (String)table.get(custId);
className = TrackingLimiter.class.getPackage().getName() + "." + className;
limiter = (TrackingLimiter) Class.forName(className).newInstance();
Are you sure you don't forget package name and class ConcreteStrategy is available for classloader?
Assuming that classname you provide to forName() is fully qualified and correct.
ClassNotFoundException
means exactly that.
So you need to ensure that the ConcreteStrategy.class
(or a jar file containing it) is in class path.
In case new classes are made available really dynamically, i.e. you know that when YOUR program started, ConcreteStrategy.class
did not exist, but a few hours/days later someone implemented it and put the fully qualified class name in the DB table, then along with the class name you also need the resource name (path of ConcreteStrategy.class
(or a jar file containing it)).
Once you have both, you can use URLClassLoader to create an instance of ConcreteStrategy from ConcreteStrategy.class
file or jar_with_ConcreteStrategy_class.jar
.
URLClassLoader example.
精彩评论