views:

46

answers:

2

I have a BlockingQueue implementation that's being used in a producer-consumer situation. I would like to decorate this queue so that every object that's taken from it is logged. I know what the straightforward implementation would look like: simply implement BlockingQueue and accept a BlockingQueue in the constructor to which all of the methods would delegate. Is there another way that I'm missing? A library perhaps? Something with a callback interface?

+2  A: 

I'd have thought that it would be simpler to create a class that extends the relevant implementation class for the BlockingQueue interface, and overrides the remove method, and others as required.

EDIT

Creating a wrapper is a better implementation if the OP is using more than one implementation of BlockingQueue, but it introduces a small performance hit on all operations, and other minor issues.

My point is that extending the queue class is an alternative to wrapping it. Whether it is a better alternative depends on the circumstances.

Stephen C
Are we both talking about the same interface? There's no `accept` method in the Java `BlockingQueue` interface.
scompt.com
BlockingQueue is an interface - Given this, I think the composition approach suggested by the OP is better than inheritence as it means they can swap in different BlockingQueue implementations.
Adamski
+1  A: 

An alternative you may wish to consider is dynamic proxies. This lets you use a reflection-style API in order to process requests made on a given interface - it would be very straightforward to delegate all calls to an underlying implementation, while adding some logging logic if the method name matched one of the take methods.

The disadvantage of this approach is that it adds a bit of extra overhead to all method calls (almost certainly negligible for general use though this should be a yellow flag if used in a performance-critical section), and the code can end up looking cumbersome. Ultimately what you're doing is defining exactly the same behaviour that you describe in your post, except you don't need to write each delegating method explicitly but provide a sort of wildcarded implementation.

Andrzej Doyle
Cool idea! It would be used to occasionally instrument the `BlockingQueue` with logging, so performance isn't that much of an issue. This article has an example for using a dynamic proxy for logging purposes: http://www.ibm.com/developerworks/java/library/j-jtp08305.html
scompt.com