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...
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.
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.
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
).
I think what you are looking for is the facade pattern.
In fact InputStream/Reader/stdin and OutputStream/Writer/stdout provide just that.
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.