MVP: Is it the View or the Presenter that should know of the Model?

后端 未结 4 508
名媛妹妹
名媛妹妹 2021-02-04 18:02

Relatively new to patterns, let me straight away show an example in the context of WinForms.

I have a basic MVP Passive View structure, which one should I go ahead with:

4条回答
  •  礼貌的吻别
    2021-02-04 18:33

    Strictly speaking, you should have the following rules:

    1. Model does not know the View or the Presenter.
    2. View does not know the Model or the Presenter.
    3. Presenter knows both Models and Views, but only through their interfaces.

    The Presenter coordinates all communication between the Model and the View, typically by handling events that are raised by the View. So to answer your questions:

    1) Who should know of the concrete instance of model User, View or Presenter?

    Ideally, neither. The Presenter should be communicating with UserModel through an IUserModel interface. The concrete instance is injected into the Presenter (e.g. through its constructor).

    2) What will be the benefit in that case?

    The primary benefit is for automated unit testing. You can inject mock Models or Views to test units in isolation.

    3) Suppose my Model is never dependent on the View. In that case what's wrong if View knows Model? After all UserView is made to present UserModel isn't it?

    There's nothing inherently wrong with it. There are variations of MVP that support direct communication from the View to the Model, typically to take advantage of data binding. You lose some testability in exchange for not having to write the binding code from scratch.

    4) If Presenter should interact with only interfaces of Model and View, then to call model.Save in Save eventhandler, where do I get the concrete instance of Model from?

    Depedency injection, such as the simplified example shown below.

    public class SamplePresenter
    {
         public SamplePresenter(ISampleModel model, ISampleView view)
         {
              view.Saved += (sender, e) => model.Save();
         }
    }
    
    public interface ISampleModel
    {
         void Save();
    }
    
    public interface ISampleView
    {
         void Show();
         event EventHandler Saved;
    }
    
    public class Program
    {
         [STAThread]
         static void Main()
         {
              ISampleModel model = new SampleModel();
              ISampleView view = new SampleView();
              SamplePresenter presenter = new SamplePresenter(model, view);
              view.Show();
         }
    }
    

提交回复
热议问题