How should I rewrite this?

F

Fencer

Hello, I have an abstract base class DataModelNode which has a number of
concrete subclasses. Each node can have a set of actions associated with
it. Action is an abstract base class with a number of concrete
subclasses. A given Action is created by an ActionFactory. I need be
able to register which ActionFactories work with a given node
dynamically so I wrote the following class:



package action;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import factory.action.ActionFactory;

import node.DataModelNode;

public class ActionRegistry {

public static void register(DataModelNode node, ActionFactory action) {
Set<ActionFactory> actions = null;

if (actionDecorations.containsKey(node)) {
actions = actionDecorations.get(node);
}
else {
actions = new HashSet<ActionFactory>();
}

actions.add(action);

actionDecorations.put(node, actions);
}

public static Set<ActionFactory> getActionFactories(DataModelNode
node) {
Set<ActionFactory> actionFactories = actionDecorations.get(node);

return actionFactories;
}

private static final Map<DataModelNode, Set<ActionFactory>>
actionDecorations = new HashMap<DataModelNode, Set<ActionFactory>>();
}

But when I was ready to register a certain ActionFactory with a certain
subclass of DataModelNode (i.e., when I was going to call register()), I
realised my mistake. This code requires an instance of a DataModelNode,
that won't work. I don't have any objects of the nodes when I need to
register. How should I rewrite this registry-class so I can associate
actionfactories with subclasses of DataModelNode? I can post more code
(a small, self-contained test case) if you weren't able to parse the
grammar of my question. Thanks!

- Fencer
 
S

Stefan Ram

Fencer said:
I need be able to register which ActionFactories work with a
given node dynamically so I wrote the following class:
¯¯¯¯¯
So, this is the specification.
This code requires an instance of a DataModelNode, that won't
work. I don't have any objects of the nodes when I need to
register.

Since the specification is for a /given/ object: When there
is no such object given at the call site, then the
specification seems not to match the preconditions, thus,
one of them has to be changed.
How should I rewrite this registry-class so I can associate
actionfactories with subclasses of DataModelNode?

So now the specification is to associate with /classes/, not
/objects/? To accept subclasses of a class A as arguments:

public class Main
{
interface A {}
interface B extends A {}
interface C extends A {}

public static< T extends java.lang.Class< ? extends A >>
void accept( final T t ){}

public static void main( final java.lang.String[] args )
{ accept( B.class );
accept( C.class ); }}
 
M

markspace

Fencer said:
This code requires an instance of a DataModelNode,
that won't work. I don't have any objects of the nodes when I need to
register. How should I rewrite this registry-class so I can associate
actionfactories with subclasses of DataModelNode?


Use the class object, not an instance. E.g.

ActionRegistry.register( DataModelNode.class, new ActionFactory() );

You'll have to change the type parameter to something like:

public static void register( Class<? extends DataModelNode> node,
ActionFactory action ) { ...

That's untested though. Good luck.
 
E

Ed

Hello, I have an abstract base class DataModelNode which has a number of
concrete subclasses. Each node can have a set of actions associated with
it. Action is an abstract base class with a number of concrete
subclasses. A given Action is created by an ActionFactory. I need be
able to register which ActionFactories work with a given node
dynamically so I wrote the following class:

I'm sure you have your reasons why the answer to the following will
be, "No," but I'll ask anyway: Do you really need to register this
Node-to-ActionFactory, "Dynamically," (where by, "Dynamically," you
seem to mean, "Before a concrete Node exists")?

To put this another way: given that each concrete Node must be
associated with certain concrete ActionFactory, what's wrong in having
the concrete Nodes hard-code the concrete ActionFactories with which
they are associated? Then clients can fetch the ActionFactories from
the concrete Nodes themselves, when instantiated, rather than from a
registry.


For example:

class RedNode extends DataModelNode {
Set actionFactories = new HashSet();
RedNode() {
actionFactories.add(new RedActionFactory());
actionFactories.add(new BigActionFactory));
actionFactories.add(new SuperActionFactory));
}

public Set getActionFactories() {
return actionFactories;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top