Ste*_*o L 7 java oop swing cohesion decoupling
请注意,这是一篇很长的帖子.对不起,但我想澄清一点:
我想知道如何将Swing GUI与Presentation和Business Logic分开很长一段时间.在工作中,我必须使用一个小的Swing对话框为一些数据实现3 MD Excel Export以配置导出.我们不使用像Spring这样的框架,所以我必须自己实现它.
我想完全将GUI与Business Logic分开,这些都是精确的后续任务:
当然,GUI不应该注意BL实现,反之亦然.我创建了上述所有这些任务,例如几个接口ProgressListener,LogMessageListener,JobDoneListener等,要由业务逻辑被解雇.例如,如果业务逻辑想要告诉记录,则会调用
fireLogListeners("Job has been started");
Run Code Online (Sandbox Code Playgroud)
实现公共接口LogListener +的类附加到BL,现在将通知有关"作业已启动"的日志消息.所有这些监听器此时都是由GUI本身实现的,一般看起来像这样:
public class ExportDialog extends JDialog implements ProgressListener, LogListener, JobFinishedListener, ErrorListener {
@Override
public void jobFinished(Object result){
// Create Save File dialog and save exported Data to file.
}
@Override
public void reportProgress(int steps){
progressBar.setValue(progressBar.getValue()+steps);
}
@Override
public void errorOccured(Exception ex, String additionalMessage){
ExceptionDialog dialog = new ExceptionDialog(additionalMessage, ex);
dialog.open();
}
// etc.
}
Run Code Online (Sandbox Code Playgroud)
"GUI和BL创建类"只是将GUI(作为所有这些侦听器的界面)附加到BL,它看起来像这样:
exportJob.addProgressListener(uiDialog);
exportJob.addLogListener(uiDialog);
exportJob.addJobFinishedListener(uiDialog);
exportJob.start();
Run Code Online (Sandbox Code Playgroud)
我现在对此非常不确定,因为它看起来很奇怪,因为所有新创建的侦听器接口.你有什么想法?如何将Swing GUI组件与BL分开?
编辑: 为了更好的演示目的,我在eclipse中创建了一个Demo工作区file-upload.net/download-9065013/exampleWorkspace.zip.html我也将它粘贴到了pastebin,但更好的是在eclipse中导入那些类,相当多的代码http: //pastebin.com/LR51UmMp
一些东西。
我不会在 ExportFunction 类中包含 uiDialog 代码。整个执行方法应该只是主类中的代码。ExportFunctions 的职责是“导出”而不是“显示 gui”。
public static void main(String[] args) {
ExportFunction exporter = new ExportFunction();
final ExportUIDialog uiDialog = new ExportUIDialog();
uiDialog.addActionPerformedListener(exporter);
uiDialog.pack();
uiDialog.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)
(不需要 Swing.invokeLater())
你似乎有点过度设计了。我不知道为什么您会期望有许多线程同时运行。当您按下按钮时,您只会期望一个线程运行,对吗?那么就不需要有一个actionPerformedListener 数组了。
而不是这个:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (startConditionsFulfilled()) {
fireActionListener(ActionPerformedListener.STARTJOB);
}
}
});
Run Code Online (Sandbox Code Playgroud)
为什么不只是:
final ExportJob exportJob = new ExportJob();
exportJob.addJobFinishedListener(this);
exportJob.addLogListener(this);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exportJob.start();
}
});
Run Code Online (Sandbox Code Playgroud)
这样你就可以摆脱 ExportFunction ,它实际上没有任何用途。
你似乎有很多听众。除非你真的需要它们,否则我不会打扰它们并使其尽可能简单。
代替 :
Thread.sleep(1000);
fireLogListener("Excel Sheet 2 created");
Thread.sleep(1000);
Run Code Online (Sandbox Code Playgroud)
只要有:
Thread.sleep(1000);
log("Excelt Sheet 1 created");
Thread.sleep(1000);
Run Code Online (Sandbox Code Playgroud)
其中日志是:
private void log(final String message) {
((DefaultListModel<String>) list.getModel()).addElement(message);
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以让它变得更简单、更干净。
GUI 不应该知道 BL,但 BL 必须以某种方式告诉 GUI 做什么。您可以使用大量接口进行无限抽象,但在 99.99% 的应用程序中这是不必要的,尤其是您的应用程序,它看起来相当简单。
因此,虽然您编写的代码非常好,但我会尝试简化和减少接口。它不保证那么多的工程。