package
effectivejava.creatinganddestoyingobjects;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Consider providing static factory methods instead of constructors
*
* Create properties file - Item1.properties with the following entries:
* Item1Impl1=effectivejava.creatinganddestoyingobjects.Item1Impl1
* Item1Impl2=effectivejava.creatinganddestoyingobjects.Item1Impl2
*
*/
public abstract class Item1 {
// Maps String key to corresponding Class object
private static Map implementations = null;
private static synchronized void initMapIfNecessary() {
if( implementations == null ) {
implementations = new HashMap();
// Load
implementation class names and keys from
// Properties
file, translate names into Class
// objects
using Class.forName and store mappings.
// ...
Properties
prop = new Properties();
try {
prop.load( new FileInputStream( "effectivejava/creatinganddestoyingobjects/Item1.properties"
));
} catch (IOException
e) {
System.out.println( e );
}
for
(Enumeration e = prop.propertyNames(); e.hasMoreElements();) {
Object obj = e.nextElement();
try {
implementations.put( obj , Class.forName( prop.getProperty( (String) obj ) ) );
} catch (ClassNotFoundException cnfe) {
System.out.println( cnfe );
}
}
prop = null;
}
}
public static Item1 getInstance( String key ) {
initMapIfNecessary();
Class c = (Class) implementations.get(
key );
if( c == null ) {
return new
DefaultItem1();
}
try {
return
(Item1) c.newInstance();
} catch (Exception e) {
return new
DefaultItem1();
}
}
public abstract void printClassName();
public static void main( String args[] ) {
Item1.getInstance("").printClassName();
Item1.getInstance("Item1Impl1").printClassName();
Item1.getInstance("Item1Impl2").printClassName();
}
}
class DefaultItem1 extends Item1 {
public void printClassName() {
System.out.println( "Item1" );
}
}
class Item1Impl1 extends Item1 {
public void printClassName() {
System.out.println( "Item1Impl1" );
}
}
class Item1Impl2 extends Item1 {
public void printClassName() {
System.out.println( "Item1Impl2" );
}
}