Угадайте, как я могу предоставить разные экземпляры подклассов в зависимости от идентификатора строки - PullRequest
2 голосов
/ 13 сентября 2011

У меня есть сценарий использования Factory Class, который я хочу реализовать с помощью Guice, но не знаю как.У меня есть абстрактный класс с именем Action, представляющий различные виды действий, которые пользователь может выполнять в моем приложении.Каждое из Actions является подклассом класса Action, и у каждого из них также есть идентификация типа String.Поскольку действия являются тяжелыми объектами, я не хочу, чтобы все они были созданы сразу, поэтому я предоставляю Factory для создания каждого из них в зависимости от идентификатора, который запрашивает клиент.

Factory Interface выглядит следующим образом:

public interface ActionFactory {

    Action getActionByID(String id);

}

Наша реализация этой Фабрики использует HashMap для поддержания связи между экземпляром String и так называемым ActionInstantiator, который будет предоставлять конкретный экземпляр Action.Реализация этого выглядит следующим образом:

public class ActionFactoryImpl implements ActionFactory {
    private HashMap<String, ActionInstantiator> actions;

    private static ActionFactoryImpl instance;

    protected ActionFactoryImpl(){
       this.actions=new HashMap<String, ActionInstantiator>();
       this.buildActionRelationships();
    }

    public static ActionFactoryImpl instance(){
       if(instance==null)
            instance=new ActionFactoryImpl();
       return instance;
    }

    public Action getActionByID(String id){
        ActionInstantiator ai = this.actions.get(id);
        if (ai == null) {
            String errMessage="Error. No action with the given ID:"+id;
            MessageBox.alert("Error", errMessage, null);
            throw new RuntimeException(errMessage);
        }
        return ai.getAction();
    }

    protected void buildActionRelationships(){
        this.actions.put("actionAAA",new ActionAAAInstantiator());
        this.actions.put("actionBBB",new ActionBBBInstantiator());
        .....
        .....
    }
}

Таким образом, некоторые клиенты, которые могут использовать эту фабрику и хотят, чтобы экземпляр класса ActionAAA вызывал ее следующим образом:

Action action=ActionFactoryImpl.instance().getActionByID(actionId);

Где actionId был получен во время выполнения из базы данных.

Я обнаружил, что какое-то внедрение аннотации может сделать что-то подобное, но в моем случае я думаю, что это не сработает, потому что я знаю только тот случай, когда пользователь будет запрашиватьво время выполнения, поэтому я не могу комментировать код.

Я новичок в Guice, поэтому, возможно, это что-то очень распространенное, что я не смог найти в документации, я извиняюсь, если это так.Любая помощь будет оценена.С уважением, Даниэль

1 Ответ

4 голосов
/ 13 сентября 2011

Вы хотите использовать расширение Multibindings, в частности MapBinder . Вы, вероятно, хотите, чтобы ваш тип ActionInstantiator реализовал Provider<Action>. Тогда вы можете сделать:

MapBinder<String, Action> mapbinder
     = MapBinder.newMapBinder(binder(), String.class, Action.class);
mapbinder.addBinding("actionAAA", ActionAAAInstantiator.class);
// ...

Затем вы можете ввести Map<String, Provider<Action>>, где вы хотите. Вы также сможете вводить вещи в свои ActionInstantiator s.

...