views:

101

answers:

5

I'm writing a bunch of data out from a java application that gets consumed by the end user it could be to a file, console, or an arbitrary listener. It would be nice to allow the user to specify how they want to consume this data. What approach have people taken to this sort of problem, is there a good open source solution? I could see something as simple as just using log4j with different appenders etc...

+1  A: 

Are you talking about an interface inside a Java application?

In that case simply provide an InputStream/Reader from which to read your data or accept an OutputStream/Writer to which you write your data.

If you're talking about communication with external programs then do what UNIX tools do for ages:

  • Read from stdin
  • Write to stdout

This way the user can do whatever they want:

  • Pipe in the output of some other command to your code
  • Pipe in the content of a file to your command
  • Enter the input of your command via the keyboard
  • Pipe out the output of your command to any other command or file

The InputStream/Reader/OutputStream/Writer idea is basically the same concept applied to the Java API.

Joachim Sauer
A: 

You can design your data-producing API so it works with a generic Writer or OutputStream; I personally prefer Writer because I think it makes the API nicer.

Hank Gay
The `Writer`/`OutputStream` decision should not be based on "nicer". Use a `Writer` whenever you handle character/text data and use an `OuputStream` whenever you handle binary data.
Joachim Sauer
That's a good distinction, but since he was already considering log4j appenders, it seemed like a fair bet the data in question was text, and it's shocking how few people are aware of and use `Writer`.
Hank Gay
A: 

The solution depends on the the specific interface for writing data. For example, should writes be synchronous or asynchronous? How should a write error be conveyed? ... as an exception or via a listener callback mechanism? What is the format of the data to be written (e.g. sequential text data).

Without more information it's impossible to give you a better solution but I'd say that one common abstraction for writing data to multiple locations is to use the java.io classes (InputStream / OutputStream or Reader / Writer).

Adamski
A: 

I think what you are looking for is the facade pattern.

In fact InputStream/Reader/stdin and OutputStream/Writer/stdout provide just that.

NomeN
No, you would look for the decorator pattern. The decorator pattern is what allows the user to chain writers and readers together.
monksy
I was thinking of abstracting away the exact recipient of the data, that would be done with Facade.
NomeN
A: 

Think about the form that your output data takes, and potentially what response object(s) your application needs back, and then select or create an interface that fulfils these requirements.

At the most abstract level you'll be spewing out a bunch of bytes, so an OutputStream is certainly the correct interface for a "byte receiver". One level of abstraction higher and you might be outputting text characters, in case a Writer is appropriate. If you're passing domain objects around then you'll possibly want something a bit more specific.

However I suspect that your interface doesn't need to be much more complicated than

public interface Consumer<T>
{
    public void consume(T obj);
}

possibly with a return type, if your provider cares about that sort of thing (e.g. an int to record the number of entities processed). There are undoubtedly lots of interfaces in open source projects that fit a similar pattern - after all, there's only so much variation you can have in an interface with a single unary method - but nothing springs to mind as being the "one true version" of this pattern. Besides, it's really easy to understand and since you don't have to worry about the implementation there's almost no downside to just rolling this yourself in about 60 seconds.

Andrzej Doyle