First, a brief description of the library that produced this:
I have a library that constantly listens on the provided serial port, reads in byte blocks and passes them to handle them in some meaningful way (details are not important for the question). To make the library somewhat more reusable, the processing of these bytes was abstracted with an interface (FrameProcessor). In the library itself, there are several default implementations for processing processing, which will always occur regardless of the application used. However, there is support for adding to user processors to do what is especially relevant for the application.
In addition to the bytes transmitted to these processors, there is a data object (ReceiverData) that contains information that may be of interest to most (but not guaranteed to all) processors. It is fully supported by the library itself (i.e. it is not the responsibility of the application to configure / maintain any instances of ReceiverData. They do not need to worry about how the data becomes available, just to make it available).
Currently, ReceiverData is passed as a parameter for each processor:
public interface FrameProcessor { public boolean process(byte[] frame, ReceiverData receiverData); }
However, I really do not like this approach, since it requires transferring data to something that may not necessarily take care of it. In addition, for processors that care about ReceiverData, they need to pass an object reference in all other method calls that they make (provided that these method calls must access this data).
I examined the possibility of changing FrameProcessor to an abstract class, and then defining a setter for the protected member of ReceiverData. But this also seems rude - the need to iterate over the list of all FrameProcessors and install an instance of ReceiverData.
I also thought of some kind of static streaming context object (always numbered, since the library supports listening on several ports at once). Essentially, you 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); } }
Thus, when each thread in the library started, it could simply add a link to its ReceiverData in the ThreadedContext, which would then be available as needed for processors without the need to transfer it.
This is definitely a pedantic question, as I already have a solution that works great. It only bothered me. Thoughts? Best approaches?