首先,简要介绍一下引发此问题的库:
我有一个库,它在提供的串行端口上连续侦听,读取字节块并将它们传递给以某种有意义的方式进行处理(细节对问题并不重要)。为了使库更具可重用性,处理这些字节被抽象到一个接口(FrameProcessor)。库本身中存在一些默认实现来处理无论应用程序使用它总是会发生的处理。但是,支持添加自定义处理器来执行应用程序特别关心的事情。
除了传递给这些处理器的字节之外,还有一个数据对象 (ReceiverData),其中包含大多数(但不保证是全部)处理器可能会感兴趣的信息。它完全由库本身维护(即,应用程序不负责设置/维护 ReceiverData 的任何实例。他们不必关心数据是如何可用的,只要它可用就可以了)。
现在,ReceiverData 正在作为参数传递给每个处理器:
public interface FrameProcessor {
public boolean process(byte[] frame, ReceiverData receiverData);
}
但是,我真的不喜欢这种方法,因为它需要将数据传递给可能不一定关心它的东西。此外,对于关心 ReceiverData 的处理器,他们必须在他们进行的任何其他方法调用中传递对象引用(前提是这些方法调用需要访问该数据)。
我考虑过将 FrameProcessor 更改为抽象类,然后为受保护的 ReceiverData 成员定义一个设置器。但这似乎也有点粗俗——必须遍历所有 FrameProcessors 的列表并设置 ReceiverData 实例。
我还考虑过某种静态线程上下文对象(由于库支持一次侦听多个端口,因此必须线程化)。本质上,您将拥有以下内容:
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);
}
}
这样,当库中的每个线程启动时,它只需将其 ReceiverData 的引用添加到 ThreadedContext,然后处理器可以根据需要使用该引用,而无需传递它。
这当然是一个迂腐的问题,因为我已经有了一个可以正常工作的解决方案。它只是困扰我。想法?更好的方法?