java - 3 Swing 应用程序设计 : which is the best?

标签 java model-view-controller swing architecture

<分区>

我是桌面应用程序开发的新手,今年夏天我要交付一个相当大的项目。问题是代码必须非常清晰,所以我在更新它时不会遇到(很多)麻烦。

因此,我想要一个好的“关注点分离”。对我来说最困难的部分是 View - Controller 分离。

现在,我已经阅读了很多教程、讨论等。我已经用 3 种不同的方式设计了一个迷你应用程序。该应用程序很简单:单击将标签转换为“Hello world”的按钮。

您如何看待这 3 种设计?

是否有更好的设计来满足我的期望?

设计1

View1.java :

public View1() {
    initComponents();
    this.controller = new Controller1(this);
}

private Controller1 controller;

public void updateLabel(String message){
    this.jLabel1.setText(message);
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    this.controller.doSomething();
}

private void initComponents() {
...
jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });
...}

Controller 1.java :

public class Controller1 {
    public Controller1(View1 v){
        this.view = v;
    }

    public void doSomething(){
        this.view.updateLabel("Hello world");
    }

    private View1 view;
}

设计2

View2.java :

public View2() {
        initComponents();
        this.controller = new Controller2(this);

        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                controller.doSomething();
            }
        });
    }
    public void updateLabel(String message){
        this.jLabel1.setText(message);
    }
    private Controller2 controller;
  ...

Controller2.java :

public class Controller2 {

        public Controller2(View2 v){
            this.view = v;
        }

        public void doSomething(){
            this.view.updateLabel("Hello world");
        }

        private View2 view;
}

设计三

View3.java :

public View3() {
        initComponents();
        this.controller = new Controller3(this);
        this.jButton1.addActionListener(this.controller.listener);
    }
    private Controller3 controller;
    public void updateLabel(String message){
        this.jLabel1.setText(message);
    }
...}

Controller3.java :

public class Controller3 {

    public Controller3(View3 v){
        this.view = v;
        this.listener = new MyListener(v);
    }

    private View3 view;
    public MyListener listener;
}

我的监听器.java :

public class MyListener implements ActionListener{
    private View3 view;

    public MyListener(View3 v){
        this.view = v;
    }

    public void actionPerformed(java.awt.event.ActionEvent evt) {
                this.view.updateLabel("Hello world");
            }
}

最佳答案

我不喜欢这些设计中的任何一个。您正在将 Controller 与 View 紧密耦合。假设您想在将来更改 Controller 实现,因此您将不得不进入所有类并更改类。相反,您应该注入(inject)它。有很多库可以通过 Guice 等注释为您完成此操作或 Spring但我不会去那些。这是一个更好的设计。

public class View{
private Controller controller;
   public View(Controller controller) {
       this.controller = controller;
   }
}

这是一个更简洁的设计,因为 View 不必知道 Controller 的实现是什么。您可以稍后创建一个子类并传递它。

现在通过上面的设计,我认为您可以看到您不应该将 View 传递给 Controller ​​。这又是一种不好的耦合。相反,您可以传递一个 onCallback 类,该类将在完成时执行。这是理解它的代码

jButton1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
            controller.doSomething(new Runnable(){
                    public void run(){
                        updateLabel("Hello world");
                    }               
           });
       }
});

然后在你的 Controller 中做

public void doSomething(Runnable callback){
   // do work
   SwingUtilties.invokeLater(callback);
}

如果您仔细看的话,我的建议就是移除任何类型的耦合。 View 不应该要求 Controller ,它应该被赋予。 Controller 不应该知道它应该只执行回调的 View 。这很重要,因为如果您决定不使用 Swing,那么您将不会在 Controller 中拥有所有这些对 Swing 包的依赖。

希望这一切对您有所帮助!

关于java - 3 Swing 应用程序设计 : which is the best?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6960018/

相关文章:

java - 带有 Netty4 的 Spring RestTemplate 和 AsyncRestTemplate 永远挂起

java - Spring mvc thymeleaf 。如何将白标签错误页面显示为模式或弹出窗口或 toast

java - 在 PaintComponent() 方法中变量未更改

java - Swing:从对话框的按钮中删除焦点边框

JAVA - 一个简单的服务器看到客户端的困难

java - 在所有 Activity 按钮上设置 setOnClickListener() 的简单方法

java - SIP 和 Java,从哪里开始?用什么开始?

java.security.Principal - 在 HttpServletRequest 和 Spring Security 中创建

javascript - 对象不是函数(MVC Javascript)

java - 使用 GroupLayout 创建自定义 GUI