MVP入门

刚刚转入C#开发不久,发现了一个类似于Java里的MVC模式的东东——MVP(Model View Presenter) 模式,个人感觉MVP模式真的和MVC差不多,MVC我这里就不解释了,着重讲讲MVP,MVP 里的M 其实和MVC里的M是一个,都是封装了核心数据、逻辑和功能的计算关系的模型(这里我们不做重点介绍),而V是视图(窗体),P我认为就是封装了窗体中的所有操作、响应用户的输入输出、事件等,个人感觉和MVC里的C差不多,区别是MVC是系统级架构的,而MVP是用在某个特定页面上的,也就是说MVP的灵活性要远远大于MVC,实现起来也极为简单。   下面以一个实例来讲接,先看源码:一共三个文件:
                    "接口:ITestMvpView"、"窗体:FrmTestMvp"," Presenter TestMvpPresenter"
先看ITestMvpView代码:


namespace TEST_MVP
{
    //声明委托
    public delegate void Button1_Click();

    interface ITestMvpView
    {
        //声明控件
        TextBox TextBox1{get;}
        //事件
        event Button1_Click Click;
    }
}

窗体代码:


namespace TEST_MVP
{
    public partial class FrmTestMvp : Form, ITestMvpView
    {
        private TestMvpPresenter _testMvpPresenter;

        public FrmTestMvp()
        {
            InitializeComponent();
            //注意构造Presenter时需把自身传过去
            this._testMvpPresenter = new TestMvpPresenter(this);
        }

        //单击按钮事件
        private void button1_Click(object sender, EventArgs e)
        {
            if (Click != null)
            {
                Click();
            }
        }

        #region ITestMvpView 成员

        //实现接口属性方法
        public TextBox TextBox1
        {
            get { return this.textBox1; }
        }

        //委托事件
        public new event Button1_Click Click;
     
        #endregion
    }
}

Presenter 代码:


namespace TEST_MVP
{
 
    class TestMvpPresenter
    {
        private ITestMvpView _testMvpView;

       // 构造函数,传入视图接口
            public TestMvpPresenter(ITestMvpView testMvpView)
        {
            this._testMvpView = testMvpView;
            this.InitEvent();
        }

        //加载委托事件
        private void InitEvent()
        {
            this._testMvpView.Click += new Button1_Click(_testMvpView_Click);
        }

        //处理事件
        void _testMvpView_Click()
        {
            if (CheckValue())
            {
                this.ShowMessage(this._testMvpView.TextBox1.Text);
            }
            else
            {
                this.ShowMessage("输入的值不能为空!");
                this._testMvpView.TextBox1.Focus();
            }          
        }

        //检查TestBox1的输入值是否合法
        private bool CheckValue()
        {
            if (this._testMvpView.TextBox1.Text.ToString() == "")
            {
                return false;
            }
            return true;
        }

        private void ShowMessage(string message)
        {
            MessageBox.Show(message);
        }
    }

        由上面的代码我们可以看出其实接口里声明的事件和控件都是要在Presenter里要处理窗体中的信息,TextBox控件如此、委托事件也是如此,他们都是要在P中处理的。重要的是窗体必须实现IView接口并且必须New 一个P,把自身作为参数传到P里,这样在P里就可以利用多态访问窗体的成员了。并且重点是在窗体里我们可以利用委托或其他技术,把对用户输入输出、事件的响应,全部放到P里处理。因为P不知道窗体,只知道IView,所以我们可以建立多个不同的窗体来对应一个P了,只要他们的业务逻辑、事件处理相同即可,换句话说即P并不知道窗体是windwosForm的还是webForm的,他只知道IViw接口,只要是实现了IView接口的窗体就行。

所以如果能够很好的利用MVP来编程,则窗体将变得非常简单 , 甚至可以让毫无经验的编码人员来负责窗体的UI设计等,真的是很方便,另外对将来的有WebForm和WindowsForm的互相转换打下良好的技术基础,甚至你可以两套东西并行开发,采用MVP模式会使这变得极为简单。

最后本文中提到的例子可以在csdn中下载到,网址为:
http://download.csdn.net/source/279995
另外如果对MVP设计模式感兴趣的话可以到msnd上搜索,微软有专门的文章介绍,也欢迎留言和我一起讨论。

 

 

 

 

觉得你这个不是MVP模式,只是MVC模式的简单变种,MVP模式是为了剥离UI层,来达到测试驱动开发
# mc1035 发表于2008-03-19 11:43:48  IP: 60.208.111.*
对,当初写这个的时候只是初探,按照我上面的来写确实有点类似MVC,不过想表达的意思就是剥离UI层,而且我认为MVP一定要遵循一点,就是在Presenter里一定不要出现直接控制UI控件的代码,那样就失去了意义。
# mc1035 发表于2008-03-19 11:45:00  IP: 60.208.111.*
所以按照后面的标准来看,其实我这个MVP代码写错了,欢迎有兴趣的兄弟给纠正一下。
# 横刀天笑 发表于2008-03-19 15:55:15  IP: 219.238.183.*
就是在Presenter里一定不要出现直接控制UI控件的代码,那样就失去了意义。

我也觉得是,这样就涉及到UI了,就无法独立测试了,我们可以做这样个测验,看看你的MVP应用在Web上和Winform上Prensenter的代码是否需要改变
# mc1035 发表于2008-03-19 16:55:02  IP: 60.208.111.*
我上面的代码估计是不行的,你试试把Iview 中的
TextBox TextBox1{get;}
改为string textBoxText{get;set;}
然后在UI(View)中替换为
string textBoxText
{
get{return this.TextBox1.Text;}
set{this.TextBox1.Text=value}
}
然后在Presenter代码里进行相应替换例如
this._testMvpView.TextBox1.Text 替为this._testMvpView.textBoxText,这样就OK了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值