MVC - 我需要在视图中使用控制器吗? [英] MVC - do I need to use Controller in the View?

查看:23
本文介绍了MVC - 我需要在视图中使用控制器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如我在 MVC 的标准实现中所知道的,我们将控制器和模型传递给视图

As I know in the standard implementation of the MVC we pass Controller and Model to the View

但是我有点不同意这个想法.我不希望我的视图同时了解控制器和模型(哦不.也许有时视图需要模型,但我确信他可以在没有控制器知识的情况下生活)

But Im a little bit disagree with this idea. I dont want my view to know about both controller and model (oh no. maybe sometimes view needs model, but I'm sure that he can live without knowledge of controller)

我认为Controller应该管理View和Model,Model不需要知道Controller和View;视图不需要知道控制器(我不排除模型,因为视图的某些实现需要了解模型以监听模型的变化).所以我的想法是视图不需要知道控制器.

In my opinion Controller should manage View and Model, and Model doesn't need to know about controller and view; view doesnt need to know controller (I dont exclude model because some implementations of views need to know about model to listen to changes in the model). So my idea is that view doesnt need to know about controller.

1. 这是一个例子:

public class MyView implements ButtonClickListener {

    private Controller myController;
    private Button myButton;

    // I commented out the model because we dont need it now 
    // we are talking about using controller in the view

    public MyView(Controller c/*, Model m*/) {
        myController  = c;
        myButton      = new Button(); // lets say that it is "register" button
        myButton.setOnButtonClickListener(this);
    }

    public void setRegisterButtonText(String text) {
        myButton.setText(text);
    }

    @Override
    public void onClick() {
        myController.tellToModelToDoSomething();
    }

}

和控制器:

public MyController implements Controller {

     private Model model;
     private View view;

     public MyController(Model model) {

          this.model = model;
          this.view  = new MyView(this);

     }

     public void tellToModelToDoSomething() {
          model.doSomeActions();
     }


}

2. 现在我如何在不传递控制器的情况下看到这个实现:

2. And now how do I see this implementation without passing the controller:

我的观点:

public class MyView {

    private Button myButton;

    public MyView() {
        myButton = new Button();
    }

    public void setRegisterButtonText(String text) {
        myButton.setText(text);
    }

    public void setOnRegisterButtonClick(final Command command) {
        myButton.setOnButtonClickListener(new ButtonClickListener() {
                            @Override
                            public void onClick() {
                                command.execute();
                            }
                         });
    }

}

命令"界面:

public interface Command {

     void execute(/*also can handle extra params*/);

}

和控制器:

public MyController implements Controller {

 private Model model;
 private View view;

 public MyController(Model model) {

      this.model = model;
      this.view  = new MyView();

      view.setOnRegisterButtonClick(command);

 }

 public void tellToModelToDoSomething() {
      model.doSomeActions();
 }

 private Command command = new Command() {

     public void execute() {
          tellToModelToDoSomething();
     }

 };

}

那么为什么我认为在视图中使用控制器不好:

So why do I think that using controller in the view IS NOT GOOD:

我们正在混合控制器和视图实现,创建新的依赖项.

We are mixing controller and view implementations, making new dependencies.

另外我认为 View 应该只包含 VIEWS 和对它们的操作(并且使用控制器和他的一些方法已经看起来像逻辑).

Also I think that View should contain only VIEWS and operations with them (and using controller and some of his methods already looks like logic).

在第一个示例中,视图告诉控制器该做什么.你同意吗?看起来像视图控制控制器!

In the first example view tells controller what to do. Are you agree? It looks like view controls the controller!

在第二个示例中,控制器控制要做什么,并且只是告诉视图如果单击某个按钮(只有视图知道它将是哪个按钮)要做什么

In the second example controller controls what to do and just says to the view what to do if some button (only view knows what button it will be) clicked

我一直使用第二种方案,但在阅读了一本关于 mvc 的新书后,说我们需要将控制器传递给视图,我有点困惑.

I always used the second scheme, but after reading a new one book about mvc, that says that we need to pass the controller to the view, I'm a little bit confusing.

你能帮我理解为什么我错了并给我举一些例子吗?

Can you please help me to understand why am I wrong and show me some examples?

推荐答案

没有 MVC 标准,因为有很多实现.以下是许多教科书中对 MVC 的一种解释:

There is no MVC standard, as there are many implementations. Here's one interpretation of MVC that's taught in many textbooks:

这个解释中控制器的定义是它处理来自视图的事件,所以视图必须使用控制器.

The definition of the controller in this interpretation is that it handles events from the view, so the view must use the controller.

在标准 MVC 中,模型包含和公开数据,控制器操作模型并接受来自视图的事件,视图呈现模型并为控制器生成事件.

In standard MVC, the model contains and exposes data, the controller manipulates the model and accepts events from the view, and the view presents the model and generates events for the controller.

MVC 被认为是一个事务系统,其中一个事务由一个事件发起.交易通常如下所示:

MVC is considered a transactional system, where a transaction is initiated by an event. The transactions typically look like this:

  1. 在视图上生成一个事件(例如按钮点击).
  2. 事件信息从视图传递到控制器.
  3. 控制器调用模型上的方法来更改它(设置器和其他可能更新某些数据库的操作方法).

这些第一步代表了 V-C 链接和 M-C 链接.V-C 的存在是因为事件从视图传递到控制器进行处理,而不是视图直接处理它们.M-C 链接的存在是因为模型是由控制器根据触发的事件更新的.

These first steps represent the V-C link and the M-C link. V-C exists because events are passed from view to controller to be processed instead of the view handling them directly. The M-C link exists because the model is updated by the controller according to the event that was fired.

从这里开始,有两条路径.第一个:

From here, there are two paths. The first one:

  1. 交易结束.
  2. 另外,模型会触发自己的事件以表明它已更改.
  3. 视图正在侦听模型并接收事件,并更新其模型表示以反映更改.

第一个路径代表对 M-V 链接的一种解释.M-V 链接是 1) 视图从模型获取其数据的信息,以及 2) 模型在视图被修改后通知视图更新.

This first path represents one interpretation of the M-V link. The M-V link is 1) the view getting information from the model for its data, and 2) the model telling the view to update since it has been modified.

第二条路径只是一个步骤:一旦控制器处理了事件,只需刷新其所有 UI 元素即可立即更新视图.对 M-V 链接的这种解释是模型只是将其信息提供给视图,这与上面第一条路径中 M-V 链接中的点 #1 相同.

The second path is only one step: once the controller has processed the event, the view updates immediately by simply refreshing all of its UI elements. This interpretation of the M-V link is that the model simply provides its information to the view, the same as point #1 from the M-V link in the first path above.

以下是针对我所描述的 MVC 架构修改的一些代码:

Here's some of your code modified for the MVC architecture I've described:

public class MyView implements View, ModelListener {

    private Button myButton;
    private Controller controller;

    public MyView(Controller controller, Model model) {
        myButton = new Button();
        myButton.setOnButtonClickListener(new ButtonClickListener() {
            @Override
            public void onClick() {
                controller.onRegisterButtonClick();
            }
        });
        this.controller = controller;
        model.addModelListener(this);
    }

    public void setRegisterButtonText(String text) {
        myButton.setText(text);
    }

    public void modelUpdated(Model model) {
        // Update view from model
    }
}

和控制器:

public MyController implements Controller {

    private Model model;
    private View view;

    public MyController(Model model) {
        this.model = model;
        this.view  = new MyView(this, model);
    }

    private void manipulateModel() {
        model.doSomeActions();
    }

    public void onRegisterButtonClick() {
        maniuplateModel();
    }
}

然后是模型:

public class MyModel implements Model {
    private List<ModelListener> modelListeners = new ArrayList<ModelListener>();

    public void addModelListener(ModelListener ml) {
        if (!modelListeners.contains(ml)) {
            modelListeners.add(ml);
        }
    }

    public void removeModelListener(ModelListener ml) {
        modelListeners.remove(ml);
    }

    public void doSomeActions() {
        // Do something
        fireUpdate();
    }

    private void fireUpdate() {
        // Iterates backwards with indices in case listeners want to remove themselves
        for (int i = modelListeners.size() - 1; i >= 0; i-- {
            modelListener.modelUpdated(this);
        }
    }
}

ModelListener 非常简单:

public interface ModelListener {
    void modelUpdated(Model model);
}

这只是一种解释.如果你想在不同部分之间进一步解耦,你应该查看 Presentation, Abstraction, 控制 (PAC) 模式.它比 MVC 更加解耦,也非常适合分布式系统.对于简单的网络、移动、桌面应用程序来说,这有点过头了,但一些客户端/服务器应用程序和大多数云应用程序可以从这种方法中受益.

This is just one interpretation. If you want further decoupling between the different parts, you should look into the Presentation, Abstraction, Control (PAC) pattern. It's more decoupled than MVC, and is great for distributed systems as well. It's overkill for simple web, mobile, desktop applications, but some client/server applications and most cloud applications can benefit from this approach.

在 PAC 中,您有三个部分,表示、抽象和控制,但抽象和表示(模型和视图)不相互交互.相反,信息仅传入和传出控制模块.此外,您可以拥有多个 PAC 子模块,它们仅通过它们的控件相互交互,这为分布式系统提供了良好的模式.基本上,控制模块是任何数据传输的主要枢纽.

In PAC, you have three parts, presentation, abstraction, and control, but the abstraction and presentation (the model and the view) don't interact with each other. Instead, information passes only in and out of the control module. Furthermore, you can have multiple PAC sub-modules that interact with each other only through their controls, lending itself to a good pattern for distributed systems. Basically, the control module is the main hub of any data transfer.

本质上,您对 MVC 的解释可能与我的或他们的不同.重要的是您选择一种架构模式并遵循它以保持您的代码在未来可维护.你是对的,有办法进一步解耦 MVC.其实你的例子有点像PAC,只不过不是去掉了V-C链接,而是去掉了M-V链接.

Essentially, your interpretation of MVC may be different from mine or theirs. What matters is that you choose an architectural pattern and follow it to keep your code maintainable in the future. And you're right that there are ways to decouple MVC further. In fact, your example is a little bit like PAC, but instead of removing the V-C link, it removes the M-V link.

无论如何,遵循一个架构,记录你的架构(让人们知道你的解释是什么),不要偏离.

In any case, follow an architecture, document your architecture (so people know what your interpretation is), and don't stray from that.

这篇关于MVC - 我需要在视图中使用控制器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆