Hi Simo,
Sorry I was late replying. I've been away at a wedding.
Honestly, I'm not a big fan of Command<K, V, C extends Context<K, V>>. I
agree with you that the it is syntactically clunky. Moreover, I'm not
convinced that the Context design needs to be improved other than the
addition of generics. It is a simple tool that does a simple thing. A
Context allows you to pass state to commands so that a command is always
stateless.
Here are some things that I like about the current context implementation
with Generics.
For example, if we have the following classes:
public class RoomContext extends HashMap<String, Object> implements Context
{
public static final String HOUSE_NUMBER_KEY = "houseNumber";
public RoomContext() {}
public RoomContext(Map<? extends String, ? extends Object> map) {
super(map);
}
public Integer getHouseNumber() {
return get(HOUSE_NUMBER_KEY);
}
public void setHouseNumber(Integer houseNumber) {
put(HOUSE_NUMBER_KEY,
}
}
public class KitchenContext extends RoomContext {
public KitchenContext() {}
public KitchenContext(Map<? extends String, ? extends Object> map) {
super(map);
}
public static final String STOVE_NAME_KEY = "stoveName";
public String getStoveName() {
return get(STOVE_NAME_KEY);
}
public void setStoveName(String name) {
put(STOVE_NAME_KEY, name);
}
}
public class BedroomContext extends RoomContext {
public BedroomContext() {}
public BedroomContext(Map<? extends String, ? extends Object> map) {
super(map);
}
public static final String BED_COLOR_KEY = "bedColor";
public String getBedColor() {
return get(BED_COLOR_KEY);
}
public void setBedColor(String color)
// Excuse the American spelling ;)
put(BED_COLOR_KEY, color);
}
}
One of the nice things that I can do is this.
KitchenContext kitchen = getInstanceFromSomewhere();
BedroomContext bedroom = new BedroomContext(kitchen);
This would allow me to prepopulate a bedroom object with the relevant house
values and other values from kitchen that I might want to use in subclasses.
That said, sure - you could shoot yourself in the foot with this pattern
(just like any others). Nonetheless, I've used this type of
state inheritance in a number of sequential data processing scenarios and as
long as I only access the getters and setters in the Command class
everything is quite testable and it has a clear to understand contract.
Basically, this is an argument to leave Context inheriting from Map.
Then when the Command is defined as so:
public class RecordHouseNumber implements Command<? extends HouseContext> {
boolean execute(HouseContext context) throws Exception {
DataSourceOfSomeKind datasource =
SomeExternalResource.getDataSource();
datasource.storeHouseNumber(context.getHouseNumber());
}
}
I don't need to do any casting or any trickery to use beans from a context.
Also, I can just use the context in the class hierarchy that implements the
least amount of functionality needed for a given Command.
Excuse my rambling, but let's return to: Command<K, V, C extends Context<K,
V>>
I believe this is unnecessary because if we leave Command defined without
the K,V generic types like so:
public interface Command<C extends Context> {
public static final boolean CONTINUE_PROCESSING = false;
public static final boolean PROCESSING_COMPLETE = true;
boolean execute(C context) throws Exception;
}
Then we can still access the context's generic methods when we use a command
that implements generics, like so:
public class FooContext extends HashMap<String, Object> implements
Context<String, Object> {
public <T> T retrieve(String K) {
return (T)get(K);
}
}
public class FooCommand implements Command<FooContext> {
public boolean execute(FooContext context) throws Exception {
Set<Entry<String,Object>> entrySet = context.entrySet();
// do something
return true;
}
}
So, as I see it Command<K, V, C extends Context<K, V>> is unneeded.
I will draft a patch that shows, how I would suggest the API to look with
Context<K,V> instead of Context<String, Object>
Ok. I've talked too much. I hope I was able to communicate my ideas clearly.
Thank you,
-Elijah
On Fri, Sep 16, 2011 at 1:40 PM, Simone Tripodi <[email protected]>wrote:
> Hi Elijah,
> I spent some spare time trying to figure out how to improve the
> Context design, I didn't have a lot of success anyway :(
>
> * dropping the Map inheritance makes not easy maintaining the classes
> in the 'generic' package;
> * adding generics in the Context to specify K,V types, makes all the
> rest of the notation not so nice (IMHO), take a look as a sample a
> Command<K, V, C extends Context<K, V>> :?
>
> Do you have more ideas?
> Many thanks in advance, all the best!
> Simo
>
> http://people.apache.org/~simonetripodi/
> http://www.99soft.org/
>
>
>
> On Wed, Sep 14, 2011 at 4:12 AM, Elijah Zupancic <[email protected]>
> wrote:
> > Hi Everyone,
> >
> > I don't have any votes as I'm not a commiter, but I would still like to
> add
> > in my suggestion.
> >
> > After our previous exchange, I'm of the mind that we should use the
> second
> > option - that is be collection agnostic and work by composition. I may be
> > biased towards defined getters and setters, but I really like to be able
> to
> > use auto-complete, automatic code refactoring tools and static code
> analysis
> > tools. If we used only a Map, then the contract for a context becomes a
> > black box of anything. I like the way it is now where you have to
> implement
> > a Map on your context or extend ContextBase. I may be biased out of habit
> -
> > if so, please convince me (by proxy everyone else).
> >
> > Thanks,
> > -Elijah
> >
> > On Mon, Sep 12, 2011 at 12:04 AM, Simone Tripodi
> > <[email protected]>wrote:
> >
> >> Hi all guys,
> >> after mails and mails of discussions, I don't think there is a general
> >> agreement on how Context API should look alike.
> >> At the end of the discussions I figured out that, briefly resuming, we
> >> have following proposals:
> >>
> >> * be replaced by Map;
> >> * be Collection agnostic and work by composition.
> >>
> >> Please add what is missing and correct what is wrong; we need to find
> >> a general agreement before to continue working toward the 2.0 release
> >> :)
> >>
> >> TIA, all the best!!!
> >> Simo
> >>
> >> http://people.apache.org/~simonetripodi/
> >> http://www.99soft.org/
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [email protected]
> >> For additional commands, e-mail: [email protected]
> >>
> >>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>