How should I rewrite this?

Discussion in 'Java' started by Fencer, Apr 6, 2010.

  1. Fencer

    Fencer Guest

    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
     
    Fencer, Apr 6, 2010
    #1
    1. Advertisements

  2. Fencer

    Stefan Ram Guest

    ¯¯¯¯¯
    So, this is the specification.
    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.
    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 ); }}
     
    Stefan Ram, Apr 7, 2010
    #2
    1. Advertisements

  3. Fencer

    markspace Guest


    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.
     
    markspace, Apr 7, 2010
    #3
  4. Fencer

    Ed Guest

    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;
    }
    }
     
    Ed, Apr 8, 2010
    #4
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.