This is the fourth post about my experiments with a fluent I/O API. This post covers conclusions and limitations of the implementation. You can find downloads and source repository details further down the page.
In my first post, I outlined some of the goals of the API. Here's a run down of how the API measures up.
Goal: reduce the amount of code required for I/O operations
In terms of the number of characters you're required to type, the API does do its job. It won't necessarily result in fewer lines of code, but the fluent style combined with IDE code completion should make them easier to write.
Where the API might fall down is in using many external stream
types. If you have to write a bunch of
implementations just to decorate a stream, this may result in more code
than just using the core API.
Goal: be extensible
Doctor mechanism is quite powerful. It is
possible to chain a bunch of these operations together to produce a
Doctor type that transforms an input type through a
series of intermediate types to an output type.
The main weakness of the current
implementation is in its generics support. The type support is weak,
despite the fact that the types are known at compile time. Writing a
method in a parameterized type to transform a parameterized
type of a parameterized type (
another parameterized type of a parameterized type is tricky to
get working in a single compiler. Getting it working in multiple
compilers has so far proved beyond my abilities. As a result, some of
the methods just take wild cards and trust the programmer to do the
This is why many of the
implementations are static instead of being returned via strongly typed
methods (as in the
There is no advantage in doing this until stronger typing can be
enforced in other parts of the API.
Goal: interoperate with the existing java.io API and any 3rd party frameworks that build on it
Support can be added for these stream types via the
type. It would be necessary to write a support library for each I/O
Goal: reduce the opportunities for resource leaks and poor error handling
To use the API, you have to use a
Whether this will drum into people that they have to use the try/finally
pattern or not is another matter. But if all the examples do, perhaps we
can hope people will copy them.
Goal: encourage good character data transcoding
The API doesn't let the user create an
without specifying a
Charset instance. This should reduce
the number of character transcoding bugs. The API also makes it easy
(and preferable) to use UTF-8, which should reduce character-related
Goal: add some support for runtime exception handling
Switching entirely to runtime exceptions from
requires a lot of stream type decorators. The API adds limited support
for some operations, but I'm sure there is more that could be done.
Goal: be small, clean and easily understood
This one is a bit subjective. The type and method naming definitely needs work.
The API in its current form has 28 types. This is too many. Some of these should be removed and there is scope for better division via packages.
Other issues and limitations
To me, the glaring omission is NIO support. I'm sure something can be done here, but I'm still mulling over exactly what.
You can download a binary here: fluentio-0.0.1-SNAPSHOT-dist.zip
All the sources are available in a public Subversion repository.
- Part 1: introduction
- Part 2: extending the API
- Part 3: error handling
- Part 4: conclusions and downloads
Comments & criticism are welcome.