migrate enums

56 views
Skip to first unread message

klc

unread,
May 26, 2015, 7:06:33 AM5/26/15
to google...@googlegroups.com
Hi guys, thanks for all the reply before I have migrate my servlet application to guice, partly at least.

I have a question about design, we use the enum template pattern a lot, like this:

public enum Action {
ADD {
@Override
public double doAction() {...}
},
UPDATE {
@Override
public double doAction() {...}
},
DELETE{
@Override
public double doAction() {...}

public abstract double doAction();

}

This is great pattern and I have nothing against it, but you can't inject it into other class and can't inject anything into it.
Is there a similar way to do the same, but injectable?

Nate Bauernfeind

unread,
May 26, 2015, 11:54:56 AM5/26/15
to google...@googlegroups.com
What is it that you like about the pattern that you want to keep? Are you looking for static inner classes? You can couple the pattern with an assisted inject factory, or providers depending on your use case.

public abstract class Action {
    public abstract double doAction();

    public static class ADD extends Action {
        @Override
        public double doAction() { ... }
    }

    public static class UPDATE extends Action {
        @Override
        public double doAction() { ... }
    }
    
    public static class DELETE extends Action {
        @Override
        public double doAction() { ... }
    }
}

Nate

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-guice...@googlegroups.com.
To post to this group, send email to google...@googlegroups.com.
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/3f1c0641-b8c1-4391-aab7-81e8e05608d8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

klc

unread,
May 26, 2015, 11:54:03 PM5/26/15
to google...@googlegroups.com
I like the pattern concise and simple, in our service class:

Action action = Action.parse(request.getAction());
action.doAction();

If I migrate them to static inner class, would it be like this?

Action action = ActionFactory.create(request.getAction()));
action.doAction();

klc

Nate Bauernfeind

unread,
May 27, 2015, 12:17:55 AM5/27/15
to google...@googlegroups.com
I want to say yes, but I'm afraid that request.getAction() is returning a string. Is this true? What would you expect your factory to look like?

If they're strings you might have to resort to something like this:

interface ActionFactory {
  public Action.ADD newAdd();
  public Action.UPDATE newUpdate();
  public Action.DELETE newDelete();
}

public abstract class Action {
    public abstract double doAction();

    public static class ADD extends Action {
        @Override
        public double doAction() { ... }
    }

    // ...

    public static Action parse(String action, ActionFactory factory) {
        switch(action) {
          case "ADD":
            return factory.newAdd();
           ...
        }
    }
}

It's not too bad. If getAction() returns something that is typesafe then you can have multiple overloaded "create" methods in your factory and do without the Action.parse method. It also might make sense to use this pattern in addition to having an enum, and then parse the enum and pass the enum into Action.parse instead of the String.


Nate Bauernfeind

unread,
May 27, 2015, 12:23:20 AM5/27/15
to google...@googlegroups.com
Oh yeah, I forgot to mention, I love making my factories inner static interfaces! It *really* helps keep relevant things together. Doing that here is also a natural choice.

Fred Faber

unread,
May 27, 2015, 12:26:49 AM5/27/15
to google...@googlegroups.com
Not taking away from other suggestions, but it's fairly idiomatic to use a MapBinder in this scenario. You'd inject the Map<String, Action> into your servlet and .get(request.getAction()).doAction();

Fred



Nate Bauernfeind

unread,
May 27, 2015, 1:20:28 AM5/27/15
to google...@googlegroups.com
That's a great suggestion, especially if you're not planning on using the assisted side of assisted injection. Note that MapBinder will also create a binding for Map<String, Provider<Action>> if you don't want your Action instances to be treated as singletons.

Reply all
Reply to author
Forward
0 new messages