On Mon, Sep 14, 2009 at 2:11 AM, Adam Murdoch <[email protected]> wrote:
> > > John Murph wrote: > >> I have my latest iteration up on GitHub (at [email protected]:jmurph/gradle.git >> branch listener_manager). I (think I) did everything you requested except >> >> 1) I left the StandardOutputListener and StandardErrorListener stuff >> combined into a single StandardOutputListener because it just seems like >> those are really one concept and having a single listener made more sense to >> me. >> >> > There's actually 2 concepts here: > - The type of event being received. In this case, we're receiving log > message events. > - The source of the events. In this case, there's 2 sources, namely stdout > log messages and stderr log messages. > > The problem with using a single interface for these 2 concepts is that you > statically bind the concepts together. This forces every listener > implementation to deal with the source, even if when doesn't care. For > example, a logging listener which just appends all logging messages to a > text panel must deal with both stdout and stderr events, even though it does > not care about the distinction. This makes it more difficult to write > reusable, composable listener implementations that you can wire together > (dynamically) in different ways. > > Another problem with static sources in the listener interface is that you > can't change the set of sources without changing the interface. Or > introducing another, very similar, interface. The set of sources we care > about are quite likely to change. For example, we might want to add some way > to receive all the logging events generated by Ant, regardless of whether > they end up on stdout or stderr. Or perhaps all logging events generated at > info log level. Or perhaps the stderr logging events generated by the build > script. > > As a general pattern, I think we should provide small listener interfaces > with maybe 1 method, or possibly 2 methods for a started/completed type > event stream. The interfaces should not encode the source in the names of > the methods (as a parameter of the method is fine). A listener can pick and > choose which of these interfaces it wants to implement. This makes us > resilient to change, and allows listeners to be composed from reusable > pieces. > I think that's generally a good rule, but rules have exceptions for a reason, and I think this is one. If stdout and stderr were really different sources, I would agree with you. Since they are two sides of the same coin, and always paired together your argument seems overly academic. But really, I would change it except I'm not sure how. The design of ListenerManager is that listeners are defined by their type, not by usage. That's because in most cases the two are the same, and I didn't like the redundancy. So, I have a couple of options for splitting these streams back apart but I don't like any of them. 1) Rename the original StandardOutputListener to StandardStreamListener. Make two subtypes StandardOutputListener and StandardErrorListener that extend StandardStreamListener by are empty. These would be marker interfaces just to allow ListenerManager and friends to talk about type instead of usage. 2) Change the original StandardOutputListener's onOutput method to take a source parameter (of type String, or some stronger type?). This would allow one interface to be used for multiple purposes, but causes listeners to get feedback for all sources, even ones they might now know about (such as Ant events). This is probably the smallest change. 3) Change ListenerManager to be are of usage. So, a listener would be registered along with a (optional?) usage identifier. When a broadcaster is requested, the type of the listener and it's intended usage would have to be given. This complicates ListenerManager and it's usage but supports these kinds of situations in the future without requiring that 1) or 2) be done again for each case. My vote would obviously be to leave the two streams combined. What about you (you here means more than just Adam, if anyone else cares I would love to hear your opinions)? -- John Murph Automated Logic Research Team
