【问题标题】:What is the correct way of Message Passing between Classes in MVC?MVC中类之间消息传递的正确方法是什么?
【发布时间】:2014-11-26 03:51:16
【问题描述】:
public void Model {
    private SwingPropertyChangeSupport spcs;
    public void updatedb();
    public void addPropertyChangeListener(PropertyChangeListener listener)
}
public void Gui {
    private JFrame view;
    Gui() {
       view = new JFrame();  
       init();// for initilizing ui components
       EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    view.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });  
    }
    void addListener(ActionListener a);
    void init();
    void updateGUI();
}

public void Controller implements ActionListener,PropertyChangeListener {
     Model m;
     Gui g;
     public void PropertyChange(PropertyChangeEvent e);
     public void actionPerformed(ActionEvent e)
     Controller(Model m,Gui g){}

}
  1. 在 3 个类之间传递消息的正确方式是什么 MVC message passsing Image 如何为多个控制器和视图扩展它?我已阅读 SO 答案 The MVC pattern and SWING 说这种实现效率不高?

  2. 以及制作控制器 ActionListener 和 PropertyChangeListener 是否正确?当我在 actionperformed() 中调用 updatedb() 时,它是否会使 GUI 变得迟缓?我还阅读了有关 View 具有 Controller 的引用,它将 gui 操作映射到模型操作.这种方式效率更高吗?

  3. 哪部分代码应该在 EventQueue.invokeLater 中?将 init() 函数放在 run() 之外是否正确?或者我应该将整个 gui 类包装在 run 中吗?


EventQueue.invokeLater(new Runnable() {

    public void run() {
        try {
            Gui view = new Gui();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

【问题讨论】:

  • 有好几个。您可以创建一系列每个级别都需要实现的合同/接口,这将允许您定义每个元素的期望,您还可以使用Observer Pattern,这将允许向感兴趣的各方提供事件通知作为一对想法
  • 但我正在寻找遵循设计原则的方法 - 低耦合和高内聚。
  • 好吧,这两种建议机制都没有高耦合,因为它们依赖于接口而不是实现,它们提供了一个高度定义的契约,每个级别都应该遵守并在其中工作。您需要问的问题是,在特定情况下哪一个是正确的......

标签: java swing oop design-patterns model-view-controller


【解决方案1】:

在 3 个类之间传递消息的正确方法是什么?

这归结为个人需求,我为每个级别定义合同/接口,并为每个子级别提供参考。也就是说,模型和控制器有一个必须满足的契约,视图和控制器有一个必须满足的契约,以便于通信。

这允许一对一的通信管道,它还将每一层解耦,因为它们不关心另一层的实现方式。

同样,您可以使用某种Observer Pattern,它允许相关方将自己注册到一个对象,以便在发生某些更改时通知他们。通常,这会从可观察对象向许多观察者创建一种单向通信。

以及制作Controller ActionListener和PropertyChangeListener是否正确?

就个人而言,控制器应该尽可能少地了解 UI 的物理实现方式。如果您的查看器合约提供 ActionListener 和/或 PropertyChangeListener 支持,那没关系,但如果您依赖底层实现对象,那可能不是一个好主意(恕我直言) - 它会增加耦合。

当我在 actionperformed() 中调用 updatedb() 时,它会使 GUI 变得迟缓吗?

您在 GUI 的主线程(例如 Swing 中的事件调度线程)的上下文中执行的任何操作都会阻止 UI 响应其事件队列中的新事件。您阻止 GUI 的主线程运行的时间越长,您的 UI 响应就越慢。简短的回答,不要用长时间运行或阻塞的进程阻塞 GUI 的主线程......

我还读到了 View 引用了 Controller ,它将 gui 动作映射到模型动作。这种方式效率更高吗?

一般来说,视图和模型实际上不应该相互通信,它们应该通过控制器进行通信。视图和控制器需要相互了解,模型和控制器需要相互了解。

知识的数量取决于合同的要求,例如,如果您使用Observer Pattern,则可观察对象不需要知道任何关于观察者的信息(除了他们拥有一个或他们可以调用的更多方法)

哪一部分代码应该在 EventQueue.invokeLater 中?将 init() 函数放在 run() 之外是否正确?或者我应该将整个 gui 类包装在 run 中吗?

任何创建或修改 UI 或 UI 组件的代码都必须在 GUI 主线程的上下文中运行。

您还可以查看 Implementing the Controller part of MVC in Java Swing 和 Java and GUI - Where do ActionListeners belong according to MVC pattern? 以了解有关 Swing 中 MVC 的更多讨论...

【讨论】:

  • 我想知道制作Controler actionlistener是否让它运行在哪个线程EVT或主线程上?
  • 您能否明确说明在这种情况下 EVT 调用了哪些函数,例如,如果我使用提交按钮输入文本,因为我读到理想情况下 setText() 方法和其他更改组件的方法必须是从 EDT 本身调用。以及我是否会遇到使用控制器更新视图的任何问题,因为当时 EDT 将执行 actionperformed 函数。
  • 除非另有说明,否则可以合理地假设来自视图的任何通知都可能在 EDT 的上下文中执行。如果您的控制器通过执行长时间运行的进程或阻塞调用来响应这些消息,那么它将阻塞 EDT...
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
相关资源
最近更新 更多