MVP模式基本用例开发

C# MVP模式基本用例开发

一、MVP 全称: Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想相似:Presenter负责逻辑的处理,Model提供数据源,View展现前台显示。
Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现,避免View里面进行业务操作。Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,即重用!
二、MVP的框架使得我们修改View界面的同时,不再影响其逻辑结构。在Web端,相似的MVC架构具有很强的优势。
MVP模式
三、优点
1、Model与View完全分离,我们可以修改View而不影响Model
2、可以更高效地使用Model,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个View,而不需要改变Presenter的逻辑。这个特性非常的有用,因为View的变化总是比Model的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
四、下面我们简单写了一个用例。
本人从事医疗行业有一两年,也接触了一些公司自己的框架,在开发过程中也有很多想法。为了解决代码之间的耦合。针对此情况,尝试用MVP架构写了一个用例。
1.整体结构如下:整体MVP代码结构
Model层我们暂时弱化,下图附Model层部分代码(该代码在PackageDrugCheck.Bizlogic.DrugStore类下):

       ///model实体,根据表结构设计
       /// 该层也可执行非查询的数据库操作
       ///枚举自己设计
    /// </summary>
   
    public class PackageModel 
    {

        public PackageModel()
        {
        }

        #region 变量

        /// <summary>
        /// 二维码
        /// </summary>
        private string ID = "";

        /// <summary>
        /// 执行流水号
        /// </summary>
        private string exen_sqn = "";

        /// <summary>
        /// 医嘱流水号
        /// </summary>
        private string orderID = "";

        /// <summary>
        /// 药品编码
        /// </summary>
        private string drugCode = "";

        /// <summary>
        /// 药品名称
        /// </summary>
        private string drugName = "";

        /// <summary>
        /// 规格
        /// </summary>
        private string drugSpecs = "";

        /// <summary>
        /// 药品属性
        /// </summary>
        private string drugProperty = "";

        /// <summary>
        /// 医嘱组合号
        /// </summary>
        private string combNO = "";

        /// <summary>
        /// 给药途径
        /// </summary>
        private string usage = "";

        /// <summary>
        /// 每次量
        /// </summary>
        private string onceDose = "";

        /// <summary>
        /// 剂量单位
        /// </summary>
        private string doseUnit = "";

        /// <summary>
        /// 用药频次
        /// </summary>
        private string frequency = "";

        /// <summary>
        /// 用药天数
        /// </summary>
        private string days = "";
        }

相应查询数据库的信息均可返回该实体存储,这里忽略。
2、VIew层我们通过控件BaseContorl的初始化加载,通过添加tapPage页的方式添加主页面。如果主页面为Winform则需要设置TopLevel 属性为false。

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PackgeDrugCheck.Compont
{
    public partial class BaseContorl :UserControl
    {
        public BaseContorl()
        {
            InitializeComponent();
        }
        protected override void OnLoad(EventArgs e)
        {
            var presenter = new PackageDrugCheck.Presenter.DrugPresenter();
            var viewForm = new fmPackageDrugCheck();
            viewForm.RegisterPresenterEventHandlers(presenter);
            presenter.SetViewer(viewForm);
            viewForm.Location = new Point(0, 0);
            TabPage tp = new TabPage();
            //viewForm.TopLevel = false;
            tp.BorderStyle = BorderStyle.None;
            tp.Name = viewForm.Name;
            tp.Text = viewForm.Text;
            //tp.AutoScroll = true;
            viewForm.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControl1.TabPages.Add(tp);
            tp.Controls.Add(viewForm);
            base.OnLoad(e);
        }
    }
}

在主页面中所有交互事件均可通过RegisterPresenterEventHandlers传递。
farpoint为该主页面的子页面,更新farpoint可以通过接口实现的方式更新。
所有实体或者数据更新都可通过接口在主页面实现的方式实现。

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PackgeDrugCheck.Compont
{
    /// <summary>
    /// <br></br>
    /// </summary>
 public partial class fmPackageDrugCheck : UserControl,PackageDrugCheck.Presenter.IICheck
    {
        public fmPackageDrugCheck()
        {
            InitializeComponent();
        }
        public void RegisterPresenterEventHandlers(PackageDrugCheck.Presenter.DrugPresenter presenter)
        {
            this.textBox1.KeyPress += presenter.SetValue;
            this.tsbCheckAll.Click += presenter.CheckAll;
            this.tsbCheckNone.Click += presenter.CheckNotAll;
            this.packageDrugCheck1.CellClickEvent +=presenter.Spread1_CellClick;
            this.tsbSave.Click += presenter.Save;
            this.tsbExit.Click += presenter.Exit;
        }
        /// <summary>
        /// 点击返回值
        /// </summary>
        public DialogResult rs = DialogResult.Cancel;
        /// <summary>
        /// 获取farpoint
        /// </summary>
        public FarPoint.Win.Spread.SheetView SheetViewDrug { get {return this.packageDrugCheck1.Spread1_Sheet1; } }
        public System.Windows.Forms.TextBox textBox { get { return this.textBox1; } }
        /// <summary>
        /// 扫码事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
        }
private void packageDrugCheck1_Load(object sender, EventArgs e)
        {

        }
          private void packageDrugCheck1_click(object sender, FarPoint.Win.Spread.CellClickEventArgs e) 
        {
            
        }
    
        #region IICheck 成员

        public int Clear()
        {  throw new NotImplementedException();
        }

        public new int Dispose()
        {
            throw new NotImplementedException();
        }

        public void Filter(string filterStr)
        {
            throw new NotImplementedException();
        }

        public int GetCarNo(ref string Query)
        {  throw new NotImplementedException();
        }

        public DataTable InitDataTable()
        {
            throw new NotImplementedException();
        }

        public int Print()
        {
            throw new NotImplementedException();
        }

        public int Save()
        {
            throw new NotImplementedException();
        }

        FarPoint.Win.Spread.SheetView PackageDrugCheck.Presenter.IICheck.SheetViewDrug
        {
            get { return this.packageDrugCheck1.Spread1_Sheet1; }
        }

        public int ShowData()
        {
            throw new NotImplementedException();
        }
        //public TextBox  textBox
        //{
        //    get { return this.textBox1; }
        //}

        #endregion

        private void tsbCheckNone_Click(object sender, EventArgs e)
        {

        }

        private void packageDrugCheck1_Click(object sender, EventArgs e)
        {

        }

        private void tsbCheckAll_Click(object sender, EventArgs e)
        {

        }

        private void tsbSave_Click(object sender, EventArgs e)
        {

        }

        private void tsbExit_Click(object sender, EventArgs e)
        {
        }
    }   
}

farpoint子页面的代码:

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PackageDrugCheck.Compont
{
    public partial class PackageDrugCheck : UserControl
    {
        public PackageDrugCheck()
        {
            InitializeComponent();
        }
        /// <summary>
        /// farpint 勾选框选择事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void CellClickHandler(object sender, FarPoint.Win.Spread.CellClickEventArgs e);
        /// <summary>
        /// 点击事件
        /// </summary>
        public event CellClickHandler CellClickEvent;
        public void setValue(string Query) 
        {

        }

        private void  Spread1_CellClick(object sender, FarPoint.Win.Spread.CellClickEventArgs e)
        {
            if (CellClickEvent != null) 
            {
                this.CellClickEvent(null, e);
            }
        }
    }
}

该页面存在点击事件,通过委托的方式通知主页面程序。
目前主页面的功能包括一些farpoint点击,获取功能,Text等事件,但是我们都没有具体实现其功能。
4。接口层代码如下,实现presenter层更新View层。

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PackageDrugCheck.Presenter
{
    public interface IICheck
    {
        /// <summary>
        /// 数据表初始化
        /// </summary>
        /// <returns>成功返回1 失败返回-1</returns>
        System.Data.DataTable InitDataTable();
        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        int Save();
        /// <summary>
        /// 显示信息
        /// </summary>
        /// <returns></returns>
        int ShowData();
        /// <summary>
        /// 清屏
        /// </summary>
        /// <returns>成功返回1 失败返回-1</returns>
        int Clear();
        /// <summary>
        /// 过滤
        /// </summary>
        /// <param name="filterStr">过滤数值</param>
        void Filter(string filterStr);
        /// <summary>
        /// 打印
        /// </summary>
        /// <returns>成功返回1 失败返回-1</returns>
        int Print();
        /// <summary>
        /// 注销处理
        /// </summary>
        /// <returns></returns>
        int Dispose();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="presenter"></param>
        void RegisterPresenterEventHandlers(DrugPresenter presenter);
        /// <summary>
        /// 获取码
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        int GetCarNo(ref string Query);
        /// <summary>
        /// farpoint
        /// </summary>
        ///所有的控件更新都可以通过接口实现更新
        FarPoint.Win.Spread.SheetView SheetViewDrug { get; }
        /// <summary>
        /// 输入框
        /// </summary>
        System.Windows.Forms.TextBox textBox { get; }
    }
}

5.presenter层,具有相应更新farpoint等的实现方法:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Data;
using System.ComponentModel;

namespace PackageDrugCheck.Presenter
{
    public class DrugPresenter
    {
        public IICheck View { get; private set; }
        /// <summary>
        /// 检验所需的键
        /// </summary>
        private string privKey = "";
        /// <summary>
        /// 现存标签数据
        /// </summary>
        private Hashtable HashTable = new Hashtable();
        /// <summary>
        /// 全选或全不选时是否只处理选择的行
        /// </summary>
        private bool isCheckSelect = false;
        /// <summary>
        /// 操作员
        /// </summary>
        private string oper = "";
        /// <summary>
        /// 操作科室
        /// </summary>
        private string operDept = "";
        /// <summary>
        /// 全选或全不选时是否只处理选择的行
        /// </summary>
        [Description("全选或全不选时是否只处理选择的行"), Category("设置"), DefaultValue(false)]
        public bool CheckSelect
        {
            get
            {
                return this.isCheckSelect;
            }
            set
            {
                this.isCheckSelect = value;
            }
        }

        public void SetViewer(IICheck view)
        {
            this.View = view;
            this.OnViewSet();
        }
        public void SetValue(object sender, KeyPressEventArgs e)
        {
            string CardNo = string.Empty;
            View.GetCarNo(ref CardNo);
            if (!(CardNo == string.Empty))
            {
                ArrayList al = new ArrayList();
                //al=....获取数据
                if (al != null && al.Count > 0)
                {
                    this.AddData(al);
                    this.View.textBox.Text = "";
                }
                else
                {
                    MessageBox.Show("输入的数据有误,查不到信息");
                    this.View.textBox.Text = "";
                    return;
                }
            }
        }
        protected virtual void OnViewSet()
        {
            oper = "00011";
            operDept = "AAA";//操作科室;
        }

        public int SetData(string CardNo)
        {
            return 1;
        }
        /// <summary>
        /// 循环添加数据默认一个单剂量一次
        /// </summary>
        /// <param name="appList"></param>
        public void AddData(ArrayList appList)
        {
            int index = this.View.SheetViewDrug.Rows.Count == 0 ? 0 : this.View.SheetViewDrug.Rows.Count;//获取当前索引
            int BackIndex = index;//铺checkBox需要
            this.View.SheetViewDrug.Rows.Count += appList.Count;
            foreach (PackageDrugCheck.Bizlogic.PackageModel app in appList)
            {
                this.AddDataToFpDetail(app, index++);
            }
        }
        /// <summary>
        /// 向FpDetail加入数据
        /// </summary>
        /// <param name="i"></param>
        protected void AddDataToFpDetail(PackageDrugCheck.Bizlogic.PackageModel app, int iIndex)
        {
            FarPoint.Win.Spread.CellType.CheckBoxCellType checkBoxCellType1 = new

FarPoint.Win.Spread.CellType.CheckBoxCellType();
            this.View.SheetViewDrug.Cells.Get(iIndex, 0).CellType = checkBoxCellType1;
            this.View.SheetViewDrug.Cells.Get(iIndex, 3).CellType = checkBoxCellType1;
            this.View.SheetViewDrug.Cells[iIndex, 0].Locked = true;
            this.View.SheetViewDrug.Cells[iIndex, 3].Locked = true;
            this.View.SheetViewDrug.Cells[iIndex, 0].Value = app.ID;
            this.View.SheetViewDrug.Cells[iIndex, 0].Value = app.exen_sqn;
            //......赋值,省略
            this.View.SheetViewDrug.Rows[iIndex].Tag = app;
        }
        /// <summary>
        /// 清空方法
        /// </summary>
        private void Clear()
        {
            this.View.textBox.Text = "";
            this.View.SheetViewDrug.Rows.Count = 0;
            HashTable.Clear();
        }
        /// <summary>
        /// 全选
        /// </summary>
        public void CheckAll(object sender, EventArgs e)
        {

            for (int i = 0; i < this.View.SheetViewDrug.Rows.Count; i++)
            {
                if (this.isCheckSelect && !this.View.SheetViewDrug.IsSelected(i, 0))
                    continue;
                this.View.SheetViewDrug.Cells[i, 3].Value = true;
                if (this.View.SheetViewDrug.Cells[i, 0].CellType is FarPoint.Win.Spread.CellType.CheckBoxCellType)
                {
                    this.View.SheetViewDrug.Cells[i, 0].Value = true;
                }

            }
        }
        /// <summary>
        /// 全不选
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void CheckNotAll(object sender, EventArgs e)
        {
            for (int i = 0; i < this.View.SheetViewDrug.Rows.Count; i++)
            {
                if (this.isCheckSelect && !this.View.SheetViewDrug.IsSelected(i, 0))
                    continue;
                this.View.SheetViewDrug.Cells[i, 3].Value = false;
                if (this.View.SheetViewDrug.Cells[i, 0].CellType is FarPoint.Win.Spread.CellType.CheckBoxCellType)
                {
                    this.View.SheetViewDrug.Cells[i, 0].Value = false;
                }

            }

        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Save(object sender, EventArgs e)
        {
          
        }

        /// <summary>
        /// 获取当前用户选中的数据
        /// </summary>
        internal ArrayList GetCheckData()
        {
            ArrayList al = new ArrayList();
            for (int i = 0; i < this.View.SheetViewDrug.Rows.Count; i++)
            {
                if (Convert.ToBoolean(this.View.SheetViewDrug.Cells[i, 3].Value))
                    al.Add(this.View.SheetViewDrug.Rows[i].Tag);
            }

            return al;
        }
        /// <summary>
        /// 获取没有选中的数据
        /// </summary>
        /// <returns></returns>
        private ArrayList GetNotCheckData()
        {
            ArrayList al = new ArrayList();
            for (int i = 0; i < this.View.SheetViewDrug.Rows.Count; i++)
            {
                if (!Convert.ToBoolean(this.View.SheetViewDrug.Cells[i, 3].Value))

                    al.Add(this.View.SheetViewDrug.Rows[i].Tag);
            }
            return al;
        }
        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Exit(object sender, EventArgs e)
        {
            this.View.Clear();
        }
    }
}

至此,基于MVP基本结构的样例就搭建成功。关于Presenter与Model层之间可以采用IOC模式解决耦合性。通过接口获取实例等方法,在此先不多作介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值