我目前的项目涉及通过各种 TCP 协议将网络流量发送到多个不同的主机。我计划将其设计为“插件”类型的设计,其中可以通过实现我的接口来编写不同协议的插件并在运行时添加。
下面是我的初始设计,我想从更有经验的开发人员那里得到一些具体的指导,特别是我是否以正确的方式进行线程化,以及如何与我的 Swing GUI “对话”。
我的 Main 类是我的 GUI,它扩展了 JFrame 并使用 Netbeans 创建。单击一个按钮,我想加载模块(在这种情况下是 SSH - 不用担心我已经完成的模块的加载)。
点击按钮的代码如下:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Executor executor = Executors.newCachedThreadPool();
PluginWorker worker = new PluginWorker();
executor.execute(worker);
}
那么首先,这个 Executor 是否需要给我的工人打电话?我可以在这里使用 SwingWorker 将执行从我的 Swing GUI 中移开吗?
以下代码是我的 PluginWorker 类,它是一个旨在启动网络探测线程的类,我不确定是否需要它?SwingWorker 可能适合这个?此外,任务数组列表的大小可以轻松达到 10,000,所以这就是我选择使用 invokeAll 函数的原因?什么是最佳实践?
public class PluginWorker implements Runnable {
private final ExecutorService es = Executors.newFixedThreadPool(5);
private final Collection<GenericPlugin> tasks = new ArrayList<>();
@Override
public void run() {
SshPlugin ssh = new SshPlugin();
tasks.add(ssh);
//tasks could easily be up to 10,000 in size, so thats why I have chosen to use the invokeAll function?
try {
es.invokeAll(tasks);
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
es.shutdown();
}
}
最后,我想要的 SshPlugin 可以由任何人编写,扩展了“GenericPlugin”,它实现了我的“Plugin”接口(所以我可以强制执行 getAuthor、getDescription 等函数)并实现“Callable”。这是必需的,因此我可以从 arraylist 运行 invokeAll。现在我担心我的插件被过度设计了,我真的需要从 GenericPlugin 扩展,我的 SSHPlugin 直接实现“插件”和“可调用”本身会更好吗?