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

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

问题描述

我知道在MVC的标准实现中,我们将Controller和Model传递给View



但是我有点不同意这个想法。我不想让我的观点知道控制器和模型(哦不,有时可能需要看看需要的模型,但我相信他可以生活没有控制器的知识)



在我看来,控制器应该管理视图和模型,并且模型不需要知道控制器和视图;视图不需要知道控制器(我不排除模型,因为一些视图的实现需要知道模型来监听模型中的更改)。因此,我的想法是视图不需要了解控制器



1。 / p>

  public class MyView implements ButtonClickListener {

private Controller myController;
private Button myButton;

//我注释掉了模型,因为我们现在不需要它
//我们在视图中使用controller

public MyView(Controller c / *,Model m * /){
myController = c;
myButton = new 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查看视图;

public MyController(Model model){

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

}

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


}



pre> 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();
}
});
}

}

Command p>

  public interface命令{

void execute(/ *也可以处理额外的params *

}

并且控制器:

  public MyController implements Controller {

私人模型模型;
private查看视图;

public MyController(Model model){

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

view.setOnRegisterButtonClick(command);

}

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

private命令command = new Command(){

public void execute(){
tellToModelToDoSomething();
}

};

}



在视图 IS NOT GOOD 中使用控制器:



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



我认为View应该只包含VIEWS和它们的操作(并且使用controller和他的一些方法已经看起来像逻辑)。



在第一个例子视图告诉控制器做什么。你同意吗?它看起来像视图控制控制器!



在第二个例子中,控制器控制做什么,只是说如果一些按钮做什么,只有视图知道什么按钮它会被)点击



我总是使用第二个方案,但是在读了一本关于mvc的新书之后,我们需要将控制器传递给视图,我有点混乱。



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

解决方案

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



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



在标准MVC中,模型包含并暴露数据,控制器操作模型并从视图接受事件,视图显示模型,控制器。



MVC被认为是事务系统,事务由事件启动。交易通常如下所示:


  1. 在视图上生成一个事件(例如按钮点击)。
  2. $ b
  3. 控制器调用模型上的方法来更改它(setters和其他操作方法可能会更新一些数据库) 。

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



从这里,有两个路径。第一个:


  1. 交易结束。

  2. 另外,模型会自动触发事件



这第一个路径代表MV链接的一个解释。 MV链接是1)从模型获取其数据的信息的视图,以及2)由于它被修改,模型告诉视图更新。



路径只是一个步骤:一旦控制器处理了事件,视图立即更新刷新所有的UI元素。对MV链接的这种解释是,模型简单地向视图提供其信息,与上面第一个路径中的MV链接的点#1相同。



这里你已经为MVC架构修改了一些代码:

  public class MyView implements View,ModelListener {

private Button myButton;
private控制器控制器;

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){
//从模型更新视图
}
}

和控制器:

  public MyController implements Controller {

私人模型模型;
private查看视图;

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(){
//如果监听器想要删除自己,则使用索引向后迭代
for(int i = modelListeners.size - 1; i> = 0; i-- {
modelListener.modelUpdated(this);
}
}
}

ModelListener 很简单:

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

这只是一个解释,如果你想进一步解耦不同的部分,你应该看看演示,抽象,控制(PAC)模式。它比MVC更分离,也是分布式系统的好处。应用程序,但是一些客户端/服务器应用程序和大多数云应用程序可以从这种方法中获益。



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



基本上,您对MVC的解释可能与我的或他们的不同。重要的是,你选择一个架构模式,并遵循它,以保持你的代码在未来可维护。你是对的有进一步解耦MVC的方法。事实上,你的例子有点像PAC,但不是删除VC链接,它删除了MV链接。



在任何情况下,遵循一个架构, em>文档你的架构(所以人们知道你的解释是什么),并且不偏离。


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)

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. Here is one example:

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();
    }

}

And Controller:

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. And now how do I see this implementation without passing the controller:

My View:

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();
                            }
                         });
    }

}

"Command" interface:

public interface Command {

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

}

And Controller:

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.

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

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?

解决方案

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.

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 is considered a transactional system, where a transaction is initiated by an event. The transactions typically look like this:

  1. An event (such as a button click) is generated on the view.
  2. The event information is passed from the view to the controller.
  3. The controller calls methods on the model to change it (setters and other manipulation methods which may update some database).

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. The transaction ends.
  2. Separately, the model fires its own events to indicate it has changed.
  3. The view is listening to the model and receives the event, and updates its model representation to reflect the changes.

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.

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.

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
    }
}

And the controller:

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();
    }
}

Then the model:

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 is pretty simple:

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

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.

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.

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 - 我需要在View中使用Controller吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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