First, a brief description of the library that brought this up:
I have a library that listens continuously on a provided serial port, reading in blocks of bytes and passing them along to be processed in some meaningful way (details aren't important to the question). To make the library a bit more reusable, processing these bytes was abstracted out to an interface (FrameProcessor). A few default implementations exist in the library itself to handle processing that's always going to occur regardless of the application using it. However, there's support for adding in custom processors to do things the application specifically cares about.
Aside from the bytes being passed to these processors, there's a data object (ReceiverData) that contains information that most (but not guaranteed to be all) of the processors might find interesting. It's maintained entirely by the library itself (i.e. it isn't the responsibility of the application to setup/maintain any instances of ReceiverData. They shouldn't have to care how the data is made available, just that it is available).
Right now, ReceiverData is being passed as a parameter to each processor:
public interface FrameProcessor {
public boolean process(byte[] frame, ReceiverData receiverData);
}
However, I really don't like this approach, as it's requiring data to be passed to something that might not necessarily care about it. Also, for the processors that do care about ReceiverData, they've got to pass the object reference around in whatever other method calls they make (provided those method calls need to access that data).
I've considered changing the FrameProcessor to an abstract class and then defining a setter for a protected ReceiverData member. But that seems kind of gross as well - having to iterate over the list of all FrameProcessors and setting the ReceiverData instance.
I've also thought about some kind of static threaded context object(necessarily threaded since the library supports listening on multiple ports at once). Essentially, you'd have something like the following:
public class ThreadedContext {
private static Map<Long, ReceiverData> receiverData;
static {
receiverData = new HashMap<Long, ReceiverData>();
}
public static ReceiverData get() {
return receiverData.get(Thread.currentThread().getId());
}
public static void put(ReceiverData data) {
receiverData.put(Thread.currentThread().getId(), data);
}
}
That way, when each thread in the library started, it could just add a reference to its ReceiverData to ThreadedContext, which would then be available as needed to the processors without needing to pass it around.
This is certainly a pedantic question, as I've already got a solution that works fine. It just bothered me. Thoughts? Better approaches?