【问题标题】:Passing the Model to the View in MVC在 MVC 中将模型传递给视图
【发布时间】:2015-01-28 19:36:46
【问题描述】:

我一直将 MVC 理解为模型不应该对视图一无所知,反之亦然。然而,在我的大学课程中,使用 MVC 模式的视图示例如下:

class View implements Updatable {

    private final JButton button = new JButton("Press Me!");
    private final JTextField textField = new JTextField(10);

    //some setup of the button and textfield

    public void update(Model model) {
        if (model.morePressesAllowed()) {
            textField.setText(String.valueOf(model.count()));
        } else {
            textField.setText("Too Many!");
            button.setEnabled(false);
        }
    }
}

视图必须知道模型具有哪些方法,这对我来说似乎很奇怪。就 MVC 模式而言,将按钮和文本字段暴露给控制器并在控制器上有更新方法似乎会更好?

模型只是增加一个数字,如果它达到 5,那么 morePressesAllowed 返回 false。

模型还有一个可更新的列表,当计数器发生变化时,它会循环通过可更新并​​调用更新,虽然这比有一个列表视图要好,但似乎控制器应该负责告诉视图何时模型改变了吗?

编辑:模型是:

class Model {
    private final List<Updatable> views = new ArrayList<Updatable>();
    private int count;
    private boolean morePressesAllowed = true;
    public void addObserver(Updatable observer) {
        views.add(observer);
    }
    public void increment() {
        count++;
        if (count >= 5) {
            morePressesAllowed = false;
        }
        notifyObservers();
    }
    private void notifyObservers() {
        for (Updatable view : views) {
            view.update(this);
        }
    }
}

Controller/Main 类:(控制器也不应该创建模型和视图并且是普通的公共类吗?)

public class GuiApp {
    private View view = new View(new Controller());
    private Model pressCounter = new Model();

    class Controller implements ActionListener {
        public void actionPerformed(ActionEvent actionEvent) {
            pressCounter.increment();
        }
    }
    GuiApp() {
        pressCounter.addObserver(view);
    }
}

实际上我更喜欢这样的东西:http://www.tutorialspoint.com/design_pattern/mvc_pattern.htm 因为控制器只是包装了视图和模型的一堆方法,虽然看起来更像 MVC,但模型和视图却没有彼此了解什么,只是看起来效率低下而且更复杂?

【问题讨论】:

  • 你也可以展示一下模型吗?

标签: java model-view-controller


【解决方案1】:

在 MVC 模式方面,将按钮和文本字段暴露给控制器,并在控制器上有更新方法似乎会更好?

这会在视图和控制器之间产生耦合。重要的是,每一层都尽可能少地相互了解。您不想要一个依赖于某些文本框或按钮存在的控制器。您希望控制器将数据传递回视图,而不关心之后会发生什么。这就是视图的工作。这就是委托的全部意义所在。

模型还有一个可更新的列表,当计数器发生变化时,它会循环通过可更新并​​调用更新,虽然这比有一个列表视图要好,但似乎控制器应该负责告诉视图何时模型变了吗?

你是对的。调用模型上的方法不是视图的角色。同样,这会产生不希望的耦合。

控制器也不应该创建模型和视图并成为普通的公共类吗?

是的。我经常看到控制器与模型层或某些服务通信,然后返回模型,然后委托给视图。

因为控制器只是包装了视图和模型的一堆方法,虽然看起来更像是 MVC,因为模型和视图彼此不知道任何东西,它似乎效率更低而且更多复杂?

这些方法称为代理方法。简单地将调用委托给其他事物的方法。当您尝试在架构中维护适当的关注点分离时,它会很有帮助。这取决于您对复杂的定义。是的,它为您的控制器添加了更多方法。再说一次,当下一个开发人员出现时,如果他或她可以安全地假设您的应用程序严格遵循 MVC 架构,那么他们将更容易针对您的代码进行开发,而不是必须制定您的微优化和“变通方法”。

【讨论】:

  • “你是对的。调用模型上的方法不是视图的角色。同样,这会产生不希望的耦合。”目前是模型在视图上调用方法(虽然它不知道它是一个视图,但它只知道它是可更新的)
  • "您希望控制器将数据传递回视图" 那么只传递相关数据而不传递模型?虽然这意味着它的耦合度较低,但如果我更改模型以输出另一条数据,那么我必须更改控制器以将新数据传递给视图并更改视图以接收来自控制器的数据。而现在模型被传递给视图虽然它更加耦合,但如果模型发生变化,那么控制器就不需要了。
猜你喜欢
  • 2015-10-19
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 2020-10-24
  • 2014-09-14
  • 1970-01-01
相关资源
最近更新 更多