86 lines
2.6 KiB
Java
Raw Normal View History

2015-05-05 11:20:13 -07:00
//: patterns/trash/Trash.java
// Base class for Trash recycling examples.
package patterns.trash;
import java.util.*;
import java.lang.reflect.*;
public abstract class Trash {
private double weight;
2015-05-27 23:30:19 -07:00
public Trash(double wt) { weight = wt; }
public Trash() {}
2015-05-05 11:20:13 -07:00
public abstract double value();
public double weight() { return weight; }
// Sums the value of Trash in a bin:
2015-05-27 23:30:19 -07:00
public static <T extends Trash>
void sumValue(List<? extends T> bin) {
Iterator<? extends T> e = bin.iterator();
2015-05-05 11:20:13 -07:00
double val = 0.0f;
while(e.hasNext()) {
2015-05-27 23:30:19 -07:00
T t = e.next();
2015-05-05 11:20:13 -07:00
val += t.weight() * t.value();
2015-05-18 23:05:20 -07:00
System.out.println("weight of " +
2015-05-05 11:20:13 -07:00
// Using RTTI to get type
// information about the class:
t.getClass().getName() +
" = " + t.weight());
}
System.out.println("Total value = " + val);
}
// Remainder of class provides support for
// prototyping:
public static class PrototypeNotFoundException
extends Exception {}
public static class CannotCreateTrashException
extends Exception {}
2015-05-06 15:14:33 -07:00
private static List<Class> trashTypes =
new ArrayList<>();
@SuppressWarnings("unchecked")
2015-05-27 23:30:19 -07:00
public static <T extends Trash> T factory(Info info)
2015-05-06 15:14:33 -07:00
throws PrototypeNotFoundException,
2015-05-05 11:20:13 -07:00
CannotCreateTrashException {
2015-05-18 23:05:20 -07:00
for(Class trashType : trashTypes) {
2015-05-05 11:20:13 -07:00
// Somehow determine the new type
// to create, and create one:
2015-05-27 23:30:19 -07:00
if(trashType.getName().contains(info.id)) {
2015-05-05 11:20:13 -07:00
try {
// Get the dynamic constructor method
// that takes a double argument:
2015-05-27 23:30:19 -07:00
Constructor ctor = trashType.getConstructor(
double.class);
2015-05-06 15:14:33 -07:00
// Call the constructor to create a
2015-05-05 11:20:13 -07:00
// new object:
2015-05-27 23:30:19 -07:00
return (T)ctor.newInstance(info.data);
2015-05-06 12:09:38 -07:00
} catch(NoSuchMethodException |
SecurityException |
InstantiationException |
IllegalAccessException |
IllegalArgumentException |
InvocationTargetException ex) {
2015-05-05 11:20:13 -07:00
ex.printStackTrace();
throw new CannotCreateTrashException();
}
}
}
// Class was not in the list. Try to load it,
// but it must be in your class path!
try {
System.out.println("Loading " + info.id);
2015-05-06 15:14:33 -07:00
trashTypes.add(Class.forName(info.id));
2015-05-05 11:20:13 -07:00
} catch(Exception e) {
e.printStackTrace();
throw new PrototypeNotFoundException();
}
2015-05-06 15:14:33 -07:00
// Loaded successfully. Recursive call
2015-05-05 11:20:13 -07:00
// should work this time:
return factory(info);
}
public static class Info {
public String id;
public double data;
public Info(String name, double data) {
id = name;
this.data = data;
}
}
} ///:~