public class DynamicFactory extends Object
ICDKObject
and IChemObject
implementations. Instances can be created by registering a construction key
(DynamicFactory.ConstructorKey
) with a corresponding creator (DynamicFactory.Creator
). In
most cases a class can simply be registered by providing an interface and an
implementation register(Class, Class)
.
Internally the factory stores the object creators in a symbol table which
allows near constant time access for all registered classes.
In cases of a non-direct parameter match (e.g. Atom(Atom)
can resolve
to Atom(Element)
) the constructor is matched by invoking find(ConstructorKey)
. If a constructor was found the new key will be
registered with cache to avoid the overhead of finding the correct
constructor again.
// create an instance of the factory
DynamicFactory factory = new DynamicFactory(5);
// register some implementations
factory.register(IAtom.class, Atom.class);
factory.register(IElement.class, Element.class);
factory.register(IAtomContainer.class, AtomContainer.class);
// create an instance using the default constructor
IAtom a1 = factory.ofClass(IAtom.class);
// create an instance using a parametrised constructor
IAtom c = factory.ofClass(IAtom.class, "C");
// using a custom creator to actually invoke a constructor
// import static org.openscience.cdk.DynamicFactory.key;
// import static org.openscience.cdk.DynamicFactory.BasicCreator;
factory.register(key(IBond.class, IAtom[].class),
new BasicCreator<IAtom>(null) {
public IAtom create(Object[] objects) {
return new Bond((IAtom[]) objects);
}
});
It is not always convenient to specify a custom DynamicFactory.Creator
for
every construction type but the objects may still need some modification
directly after creation. The factory provides DynamicFactory.CreationModifier
which
is invoked directly after object creation. This allows changing the default
of creation. As an example it is possible to set a non-null charge on all
atoms that are created.
// import static org.openscience.cdk.DynamicFactory.CreationModifier;
factory.register(IAtom.class, Atom.class,
new CreationModifier<Atom>() {
public void modify(Atom atom) {
atom.setFormalCharge(0);
}
}));
It is also possible change the object creation based on the input parameters.
factory.register(key(IAtom.class, String.class),
new DynamicFactory.BasicCreator<IAtom>() {
public IAtom create(Object[] objects) {
String symbol = (String) objects[0];
return "R".equals(symbol)
? new PseudoAtom(symbol)
: new Atom(symbol);
}
});
factory.ofClass(IAtom.class, "C"); // IAtom
factory.ofClass(IAtom.class, "R"); // IPseudoAtom
Modifier and Type | Class and Description |
---|---|
static class |
DynamicFactory.BasicCreator<T>
A simple creator that helps in creating an anonymous classes for a
creator.
|
static class |
DynamicFactory.ConstructorKey
A class which encapsulates the information about an interface (of this
implementation) and the parameter types of the constructor.
|
static interface |
DynamicFactory.CreationModifier<T>
An interface that allows posterior modification of an instance after it
has been created.
|
static interface |
DynamicFactory.Creator<T>
An interface that wraps object creation via the
DynamicFactory.Creator.create(Object[])
method. |
protected static class |
DynamicFactory.DefaultInterfaceProvider
A default interface provider implementation that simply returns the
classes from
Class.getInterfaces() . |
static interface |
DynamicFactory.InterfaceProvider
An interface that can provide which interfaces the given class
implements.
|
Constructor and Description |
---|
DynamicFactory(DynamicFactory.InterfaceProvider interfaceProvider,
int n)
Create a new default factory with an expected number of registered
classes and an interface provider.
|
DynamicFactory(int n)
Create a new default factory with an expected number of registered
classes and a default interface provider.
|
Modifier and Type | Method and Description |
---|---|
<T extends ICDKObject> |
implementorsOf(Class<T> intf)
Access the registered implementations for a given interface.
|
static DynamicFactory.ConstructorKey |
key(Class<?> intf,
Class<?>... types)
Creates a constructor key for use in accessing constructors.
|
<T extends ICDKObject> |
ofClass(Class<T> intf)
Construct an implementation using the default constructor.
|
<T extends ICDKObject> |
ofClass(Class<T> intf,
Object... objects)
Construct an implementation using a constructor whose parameters match
that of the provided objects.
|
<T extends ICDKObject> |
register(Class<? extends T> impl)
Registers a class with the factory.
|
<S extends ICDKObject,T extends S> |
register(Class<S> intf,
Class<T> impl,
DynamicFactory.CreationModifier<T> modifier)
Explicitly register a concrete class with a provided interface and a
given modifier.
|
<S extends ICDKObject,T extends S> |
register(Class<S> intf,
Constructor<T> constructor)
Register a specific constructor with an explicit interface.
|
<S extends ICDKObject,T extends S> |
register(Class<S> intf,
Constructor<T> constructor,
DynamicFactory.CreationModifier<T> modifier)
Register a specific constructor with a creation modifier to an explicit
interface.
|
<T extends ICDKObject> |
register(Class<T> intf,
Class<? extends T> impl)
Explicitly register a concrete class with a provided interface.
|
<T> DynamicFactory.Creator<T> |
register(DynamicFactory.ConstructorKey key,
DynamicFactory.Creator<T> creator)
Register a constructor key with a defined
DynamicFactory.Creator . |
Iterator<DynamicFactory.ConstructorKey> |
suggest(Class<?> intf)
Provides a list of all possible constructor keys for the provided
interface.
|
public DynamicFactory(DynamicFactory.InterfaceProvider interfaceProvider, int n)
register(Class)
.interfaceProvider
- provides the interfaces of a given
implementation classn
- the expected number of constructors that will be
stored.DynamicFactory(int)
public DynamicFactory(int n)
Class.getInterfaces()
when registering an
implementation without an explicit interface register(Class)
.n
- the expected number of constructors that will be stored.public <T extends ICDKObject> boolean register(Class<? extends T> impl)
register(Class, Class)
can be used.impl
- a concrete classIllegalArgumentException
- thrown if a non-concrete class is
registeredregister(Class, Class)
,
register(Class, java.lang.reflect.Constructor)
,
register(org.openscience.cdk.DynamicFactory.ConstructorKey,
org.openscience.cdk.DynamicFactory.Creator)
public <T extends ICDKObject> boolean register(Class<T> intf, Class<? extends T> impl)
DynamicFactory.Creator
will be automatically created for all public
constructors.intf
- the interface class to registerimpl
- the concrete class which should implement the interface
classpublic <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Class<T> impl, DynamicFactory.CreationModifier<T> modifier)
DynamicFactory.Creator
will be automatically created for all
public constructors. The modifier is incorporated into the DynamicFactory.Creator
and is invoked directly after instantiation.
// import static org.openscience.cdk.DynamicFactory.CreationModifier;
factory.register(IAtom.class, Atom.class,
new CreationModifier<Atom>() {
public void modify(Atom atom) {
atom.setFormalCharge(0);
}
}));
S
- interface typeT
- implementation type (must extend interface)intf
- the interface class to registerimpl
- the concrete class which should implement the interface
classmodifier
- modify a instance after creationpublic <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Constructor<T> constructor)
// only register construction of IAtom using a string - Atom("C")
factory.register(IAtom.class,
Atom.class.getConstructor(String.class));
S
- interface typeT
- implementation type (must extend interface)intf
- the interfaceconstructor
- a constructor which builds the given interfacepublic <S extends ICDKObject,T extends S> boolean register(Class<S> intf, Constructor<T> constructor, DynamicFactory.CreationModifier<T> modifier)
// only register construction of IAtom using a string - Atom("C")
factory.register(IAtom.class,
Atom.class.getConstructor(String.class),
new DynamicFactory.CreationModifier<Atom>() {
public void modify(Atom instance) {
instance.setFormalCharge(0);
}
});
S
- interface typeT
- implementation type (must extend interface)intf
- the interfaceconstructor
- a constructor which builds the given interfacepublic <T> DynamicFactory.Creator<T> register(DynamicFactory.ConstructorKey key, DynamicFactory.Creator<T> creator)
DynamicFactory.Creator
. The key
defines the interface and parameters of the creation and the creator
actually creates the object.
// import static org.openscience.cdk.DynamicFactory.key;
factory.register(key(IBond.class, IAtom[].class),
new BasicCreator<IAtom>(null) {
public IAtom create(Object[] objects) {
return new Bond((IAtom[]) objects);
}
});
T
- type of object that will be createdkey
- construction key, defines interface and parameter typescreator
- creates the actual objectpublic static DynamicFactory.ConstructorKey key(Class<?> intf, Class<?>... types)
intf
- the interface to build the key fortypes
- the classes that the the constructor requirespublic <T extends ICDKObject> T ofClass(Class<T> intf, Object... objects)
T
- the type of the classintf
- the interface to construct an instance ofIllegalArgumentException
- thrown if the implementation can not be
constructedIllegalArgumentException
- thrown if the provided class is not an
interfacepublic <T extends ICDKObject> T ofClass(Class<T> intf)
ofClass(Class, Object...)
.T
- the type of the classintf
- the interface to construct an instance ofIllegalArgumentException
- thrown if the implementation can not be
constructedIllegalArgumentException
- thrown if the provided class is not an
interfacepublic <T extends ICDKObject> Set<Class<?>> implementorsOf(Class<T> intf)
T
- the type of the interfaceintf
- an interface which has registered implementations in the
factorypublic Iterator<DynamicFactory.ConstructorKey> suggest(Class<?> intf)
intf
- an interface to find all constructors forCopyright © 2017. All Rights Reserved.