myRoad—关于MVP模式

一,MVP模式

认识MVP模式是通过读artech的文章,在工作中使用MVP模式也是时刻想着他翻译的的CAB(Componsable Application Block)基于14条MVP规则:

 

  • 所有的View(包括View的接口)的名称应该以View作为后缀,比如TaskView/ITaskView;
  • 所有的Presenter名称应该以Presenter作为后缀,比如TaskViewPresenter;
  • Presenter完成Use Case处理逻辑,对GUI控件的处理应该在View中实现;
  • View调用Presenter的方法应该像触发事件异常,通过调用OnXxx方法的方式来实现;
  • 应该尽可能地限制View对Presenter的调用,并且调用的方式限于按照“事件”的形式,比如_presenter.OnViewReady();
  • View不允许通过Presenter直接调用Model和Service,并且Presenter的方法应该是不具有返回值的;
  • Presenter必须通过View接口的方式调用View
  • 除了对View接口成员的实现外,View中的其他方法不应该是public的;
  • 除了CAB ModuleController 对View的加载和限制外,View只能被Presenter调用;
  • View接口方法应该基于Use Case的逻辑起一个有意义的名称,比如SetDataSource这样的方法名称是不合法的;
  • View接口的成员应该仅限于方法,不应该包含属性;
  • 所有的数据应用保持在Model中
  • 定义在View接口的方法不应该包含对GUI空间名称的引用(比如AddExplorerBarGroup),因为这会使Presenter知道View太多关于实现方面的细节;
  • 尽量让View的方法名称反映Use Case的业务逻辑,这样可以使你的代码具有自表述性并更加易于理解。
  •  

二,工作中遇到的问题

 

1.工作中使用到MVP模式,在我的认识中MVP的写法是下面这样的:

 
IView,定义View的事件,和View必须实现的方法 :
 
    public interface ITestView

    {

        event Action SomeEvent;

        void ShowMessage(string msg);

    }
 
View,实现IView,并且在构造函数里初始化Presenter :
 
    public partial class TestView : Window,ITestView

    {

        TestPresenter presenter;



        public TestView()

        {

            InitializeComponent();



            presenter = new TestPresenter(this);



            this.btnSomething.Click += (sender, e) =>

                {

                    if (this.SomeEvent != null) SomeEvent();

                };

        }



        #region ITestView 成员



         public event Action SomeEvent;



        public void ShowMessage(string msg)

        {

            MessageBox.Show(msg);

        }



        #endregion

    }

Presenter构造函数需要一个实现了Iview接口的View,并绑定IView里的事件,进行处理后调用IView里定义的方法
 
    public class TestPresenter

    {

        public TestPresenter(ITestView view)

        {

            view.SomeEvent += () =>

                {

                    view.ShowMessage("MVP模式的测试");

                };

        }

    }

2.但是在工作中我们实际写的MVP模式是下面这种:

 

IView,只定义View的事件:

 

    public interface ITestView

    {

        event Action SomeEvent;

    }

 
  
    
View,实现IView,并且在构造函数里初始化Presenter,并且绑定Presenter里的事件 :
 
    public partial class TestView : Window,ITestView

    {

        TestPresenter presenter;



        public TestView()

        {

            InitializeComponent();



            presenter = new TestPresenter(this);



            presenter.ShowMessage += (msg) =>

                {

                    MessageBox.Show(msg);

                };



            this.btnSomething.Click += (sender, e) =>

                {

                    if (this.SomeEvent != null) SomeEvent();

                };

        }



        #region ITestView 成员



        public event Action SomeEvent;



        #endregion

    }

Presenter构造函数需要一个实现了Iview接口的View,并绑定IView里的事件,进行处理后调用自己定义的触发自己事件的方法:

    public class TestPresenter

    {

        public event Action<string> ShowMessage;



        private void OnShowMessage(string msg)

        {

            if (ShowMessage != null) ShowMessage(msg);

        }



        public TestPresenter(ITestView view)

        {

            view.SomeEvent += () =>

                {

                    OnShowMessage("MVP模式测试");

                };

        }

    }

 

三,自己对着两种写法的认识:

 

     第一种方法,IView需要定义用户可能会触发的事件,并且需要提供一些方法。

     我的理解是这样的IView相当清楚自己会怎么样,并且还知道自己能干什么,什么自己干不了。编写View的时候只要完成IView里定义的事件,并且把IView里定义的“能干的事情”都实现,不需要去关注Presenter里到底会怎么样。

     编写Presenter的人清楚的知道View能干什么事情,会触发什么事件。知道处理一些业务逻辑后自己该怎样去指挥View。

     自己感觉这样的方法,主控权是Presenter。View只是去执行,而且必须执行,没有选择权。(因为View继承IView接口,必须实现IView里定义的方法)

     第二种方法,IView只定义用户可能会触发的事件。

      我的理解是这样的IView只知道自己会怎么样,并不知道自己能干什么。编写View的时候需要要完成IView里定义的事件,并且需要清楚Presenter会发生什么样的事件,我要不要处理Presenter里发生的事件。

     编写Presenter的人不知道View能干什么事情,当接受到View发生的事件后,处理一些业务逻辑后,只是触发自己的事件,View层处理不处理,Presenter就不关心了。

     自己感觉这样的方法,Presenter 和 View 都回去控制一些东西,View有了选择权。(因为View可以监听Presenter的事件,也可以不监听)。

    

四,想向大家请教一些问题:

      自己老感觉MVP模式应该是第一种写法,但是和我们项目中用到的不一样,而且思想上好像有很大的差别,希望大家能给我一些指导,

第二种方法有什么好处? 真正的MVP模式处理这种问题应该是怎么写的?

你可能感兴趣的:(模式)