- Overall Application
- Ferret Interface
- Implementing the Ferret
- Instantiating the Ferret
- A Second Ferret
- Introducing the Factory
- Enabling the Factory to Use Different Classes
- Allowing the User to Choose at Runtime
- Moving On from Here
Enabling the Factory to Use Different Classes
Now that we've got the factory working, let's enable it to use different classes. One way to do that is to create a version of newFerret() that takes a class name and then dynamically instantiates that class.
NOTE
Dynamic class creation is a topic unto itself. For more information on creating classes dynamically and using introspection, check out
http://developer.java.sun.com/developer/technicalArticles/ALT/Reflection/.
First, we create a new method in the FerretFactory, as shown in Listing 8.
Listing 8 Taking In a Class Name
package org.chase.research; public class FerretFactory { public Ferret newFerret() { return new org.chase.ferrets.GoogleFinder(); } public Ferret newFerret (String classname) { Ferret theFerret = null; try { theFerret = (Ferret) Class.forName(classname).newInstance(); } catch (Exception e) { theFerret = new org.chase.ferrets.GoogleFinder(); } return theFerret; } }
In this case, if the newFerret() method has an argument, the factory will try to create a class by that name, cast it as a Ferret, and return it. If there are any problems creating a class by that nameif the class doesn't exist, for examplethe method just returns a GoogleFinder-variety Ferret.
Now, the application can be run exactly as it was by using a GoogleFinder, or we can specifically request a GoogleSpecificFinder, as shown in Listing 9.
Listing 9 Requesting a Specific Class
... String searchTerm = args[0]; FerretFactory ferretFactory = new FerretFactory(); Ferret theFerret = ferretFactory.newFerret( "org.chase.ferrets.GoogleSpecificFinder"); System.out.println("Getting Results ..."); ...
Now, if we run the application, we'll see the more sleek GoogleSpecificFinder-variety of results.
We could, in fact, add any class name here, as long as that class existed and implemented the Ferret interface.
But it still ties the application to a specific implementation of Ferret.