zoukankan      html  css  js  c++  java
  • MVP模式及实例

    最近在关注MVP模式的文章,看了张子阳的 MVP 模式实例解析和李春雷的MVP模式最佳实践(1)—MVP模式简介 ,自己也想弄一个来试试。

    关于MVP模式的概念,网上很多,在此摘抄一段吧。

    MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。Alex在他的blog中对于这两者之间的比较很直观也比较清楚,原文可以下面的地址找到:http://ameleta.spaces.live.com/blog/cns!5F6316345A821420!163.entry

    准确的说,MVP模式和三层架构相比,MVP模式的编码量比较大,我个人认为普通的项目如果不涉及到WinFrom 与WebFrom 之间的转换,最好不要用MVP的模式。

    下面我就以我所理解的MVP模式写一个小实例,是关于某个员工基本信息的数据绑定与编辑的操作。

    在员工基本信息的编辑界面中,需要展示的信息包括员工的工号,姓名,性别,籍贯,出生年月等等,在此实例中我只展示这五个字段,一个绑定员工信息的方法,以及一个更新员工信息的事件。

    首先,定义员工的Model层,该层代码与三层架构的实体层是相同的。


     1namespace Model
     2{
     3    using System;
     4    public class StaffInfo
     5    {
     6        private string _stfId;
     7        private string _stfName;
     8        private string _sex;
     9        private string _native;
    10        private string _birthDay;
    11
    12        public StaffInfo()
    13        {
    14        }

    15
    16        public StaffInfo(string stfId, string stfName, string sex, string native, string birthDay)
    17        {
    18            this._stfId = stfId;
    19            this._stfName = stfName;
    20            this._sex = sex;
    21            this._native = native;
    22            this._birthDay = birthDay;
    23        }

    24        /// <summary>
    25        /// 员工工号
    26        /// </summary>

    27        public string StfId
    28        {
    29            get return _stfId; }
    30            set { _stfId = value; }
    31        }

    32        /// <summary>
    33        /// 员工姓名
    34        /// </summary>

    35        public string StfName
    36        {
    37            get return _stfName; }
    38            set { _stfName = value; }
    39        }

    40        /// <summary>
    41        /// 性别
    42        /// </summary>

    43        public string Sex
    44        {
    45            get return _sex; }
    46            set { _sex = value; }
    47        }

    48        /// <summary>
    49        /// 籍贯
    50        /// </summary>

    51        public string Native
    52        {
    53            get return _native; }
    54            set { _native = value; }
    55        }

    56        /// <summary>
    57        /// 出生年月
    58        /// </summary>

    59        public string BirthDay
    60        {
    61            get return _birthDay; }
    62            set { _birthDay = value; }
    63        }

    64    }

    65}

     

    第二步,定义员工的页面接口 IStaffDetailView ,在页面中,一般有一些常用的自定义函数,这时我们可以把它定义在父接口,然后用一个页面父类去实现它,如下面的MessageBox这个函数,就可以用这样的方式。那么我们页面接口就可以继承这个父接口,这样可以增强代码的重用性。


     1namespace Presenter
     2{
     3    using System;
     4    using Model;
     5    public interface IStaffDetailView
     6    {
     7        /// <summary>
     8        /// 员工工号
     9        /// </summary>

    10        string StfId get;}
    11
    12        /// <summary>
    13        /// 员工姓名
    14        /// </summary>

    15        string StfName get;}
    16
    17        /// <summary>
    18        /// 性别
    19        /// </summary>

    20        string Sex get;}
    21
    22        /// <summary>
    23        /// 籍贯
    24        /// </summary>

    25        string Native get;}
    26
    27        /// <summary>
    28        /// 出生年月
    29        /// </summary>

    30        string BirthDay get;}
    31
    32        /// <summary>
    33        /// 绑定员工信息
    34        /// </summary>
    35        /// <param name="infos"></param>

    36        void BindDetail(StaffInfo> infos);
    37
    38        /// <summary>
    39        /// 更新员工信息事件
    40        /// </summary>

    41        event EventHandler<EventArgs> UpdateEvent;
    42    }

    43}

    第三步,定义员工数据访问类,我这里只是给一个示例,真实的项目中当然要封装一下才行。

    Code

    第四步,定义员工Presenter层


     1public class StaffDetailPresenter
     2    {
     3        private IStaffDetailView _view;
     4
     5        public StaffDetailPresenter(IStaffDetailView view)
     6        {
     7            this._view = view;
     8        }

     9
    10        /// <summary>
    11        /// 初始化页面
    12        /// </summary>
    13        /// <param name="IsPostBack">首次提交,WebFrom中,此值为IsPostBack,WinFrom中,此值为false</param>

    14        public void InitializeView(bool IsPostBack)
    15        {
    16            if(!IsPostBack)
    17                BindDetail();
    18            this._view.UpdateEvent += new EventHandler<EventArgs>(View_UpdateEvent);
    19        }

    20
    21        private void BindDetail()
    22        {
    23            this._view.BindDetail(new Staff(this._view.StfId));
    24        }

    25
    26        private void View_UpdateEvent(object sender, EventArgs e)
    27        {
    28            if (new Staff().UpdateStaff(new Staff(this._view.StfId, this._view.StfName, this._view.Sex, this._view.Native, this._view.BirthDay)))
    29            {
    30                this.BindDetail();
    31                this._view.MessageBox("更新成功");
    32            }

    33            else
    34                this._view.MessageBox("更新失败!");
    35        }

    36    }

    第五步:实现View接口,我这里以WebFrom为例,在页面中做了数据绑定与更新数据事件两个操作,还有如绑定GridView等等操作,大家可以探讨。


     1namespace Web
     2{
     3    using System;
     4    using System.Data;
     5    using System.Data.SqlClient;
     6    using System.Configuration;
     7    using System.Collections;
     8    using System.Collections.Generic;
     9    using System.Web;
    10    using System.Web.Security;
    11    using System.Web.UI;
    12    using System.Web.UI.WebControls;
    13    using System.Web.UI.WebControls.WebParts;
    14    using System.Web.UI.HtmlControls;
    15    using Presenter;
    16    using Model;
    17
    18    public partial class StaffDetail : Page, IStaffDetailView
    19    {
    20        #region 实现接口
    21        /// <summary>
    22        /// 员工工号
    23        /// </summary>

    24        public string StfId get if (object.Equals(Request.QueryString["stfId"], null)) return nullreturn Request.QueryString["stfId"].ToString(); } }
    25
    26        /// <summary>
    27        /// 员工姓名
    28        /// </summary>

    29        public string StfName get return txtStfName.Text; } }
    30
    31        /// <summary>
    32        /// 性别
    33        /// </summary>

    34        public string Sex get return ddlSex.SelectValue; } }
    35
    36        /// <summary>
    37        /// 籍贯
    38        /// </summary>

    39        public string Native get return txtNative.Text; } }
    40
    41        /// <summary>
    42        /// 出生年月
    43        /// </summary>

    44        public string BirthDay get return txtBirthDay.Text; } }
    45
    46        /// <summary>
    47        /// 绑定员工信息
    48        /// </summary>
    49        /// <param name="info"></param>

    50        public void BindDetail(StaffInfo info)
    51        {
    52            lbStfId.Text = info.StfId;
    53            txtStfName.Text = info.StfName;
    54            ddlSex.SelectValue = info.Sex;
    55            txtNative.Text = info.Native;
    56            txtBirthDay.Text = info.BirthDay;
    57        }

    58
    59        /// <summary>
    60        /// 弹出对话框
    61        /// </summary>
    62        /// <param name="msg">对话框消息</param>

    63        public void MessageBox(string msg)
    64        {
    65            string script = string.Format("<script language='javascript' type='text/javascript' defer>window.alert('{0}');</script>", msg);
    66            this.ClientScript.RegisterStartupScript(this.GetType(), "系统提示", script);
    67        }

    68
    69        /// <summary>
    70        /// 更新员工信息事件
    71        /// </summary>

    72        public event EventHandler<EventArgs> UpdateEvent;
    73        #endregion

    74
    75        protected void Page_Load(object sender, EventArgs e)
    76        {
    77            StaffDetailPresenter p = new StaffDetailPresenter(this);
    78            p.InitializeView(IsPostBack);
    79        }

    80
    81        protected void btn_Update(object sender, EventArgs e)
    82        {
    83            if (this.UpdateEvent != null)
    84                this.UpdateEvent(sender, e);
    85        }

    86    }

    87    
    88}

    以上是整个实例的代码。这个实例与李春雷的实例的大体结构类似,不同之处在于以下两点

    1、视图接口中增加了按钮事件,这个思路来源于http://www.cnblogs.com/chinasf/archive/2006/12/20/597987.html

    2、明确了Model层与Control层的职责,在Model层的设计中我采用了与三层框架的实体层相同的方式,DataAccess作为Control层,它的作用在于对数据库进行操作。

    欢迎大家来批评指正。

    示例别的示例

    转自:http://www.cnblogs.com/easyit/archive/2009/05/12/1454786.html

  • 相关阅读:
    clientHeight和offsetHeight
    bus事件总线传值
    解决英文溢出不换行
    小程序熏染可滑动动态导航
    个人样式小结
    数组删除元素
    vue封装swiper
    大佬的接口玩玩
    Java探针技术-JVM的动态agent机制:在main函数启动之后运行agent
    Java探针技术-Instrumentation与ClassFileTransformer--字节码转换工具
  • 原文地址:https://www.cnblogs.com/stalwart/p/1985963.html
Copyright © 2011-2022 走看看