1.MVP框架介绍: 最近公司内部培训,正好理一下项目的架构,目前最主要的产品还是用的MVP软件设计模式,就顺便查查资料来做个总结。 1.1什么是MVP? MVP是Model-View—Presenter的缩写,从网上找到的资料来看,大多数时候,对于MVP的介绍还是基于MVC,关注点基本上就集中在Presenter上面了,wiki上有个简单的说明( MVP模式),先从定义来大概理解下这个模式:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyAzN1UTN3UTOtYDN1ITM5MzMyEjMyETNxAjMtIDN5YzMz8CXyETNxAjMvwlM0kjNzMzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
1.2MVP各自的使用规则和相互的交互 这三个模块,一般情况下,对于view的理解是没什么争议的,就是界面展示;关于Model和Presenter的功能,还是有些争议,简单的来说,一个是业务逻辑,一个是界面控制逻辑,但是实际定义的时候可能就没那么清楚了,关于这两个模块定位的区分,我看到了一篇比较有用的文章,虽然是MVC的,但是原理是差不多的( 点这里查看原文):
实体对象(entity object):
通常是来自域模型中的对象(也就是现实世界),它常对应于数据库表和文件,这些数据表
和文件中存储了执行用例所需的数据。有些实体对象是“临时”对象(如搜索结果),当用例
结束后将消失。
边界对象(boundary object):
参与者使用它来同系统交互,这通常包含窗口,屏幕,对话框和菜单。如果有GUI原型,
将会知道许多主要的边界对象是什么。
控制对象(control object):
将边界对象和实体对象关联起来(通常被称为控制器,因为它们通常不是真正的对象),
它包含了大部分应用逻辑,它们在用户和存储的数据之间架起一座桥梁。控制对象中包含经常
修改的业务规则和策略。这样修改只需要在这些对象中进行,而不会涉及到用户界面和数据库
模式。控制器偶尔 (20%的时间内)也会是设计中的“真正对象”,但大部分时间内,控制器只
是一个占位符,用于避免您遗漏用例要求的任何功能和系统行为。
关于这三个模块的交互,可以用一张图来体现:
Presenter做为Model和View的中间层,维护页面操作状态,从Model获取数据,百度百科里用的图Presenter和model之间是双向绑定的,有点没看懂,原则上,Model是不会处理Presenter的。
1.3关于MVP的一些概念上的问题 我之前对于Model的理解是有些误差的,不管是MVC还是MVP,我之前以为Model是数据模型,只是数据库交互的相关操作,这本身应该算是对Model的一种弱化,实际上,参考微软提供的MVCScore的示例项目( 下载链接)可以发现,Model并不是通常意义上跟数据库中表的对应,对应的其实是后台的Service这部分,Model作为业务逻辑模型,应该承担更多业务处理工作,这样才是把业务和页面展示分开,实现前台页面和后台逻辑的解耦。 当然,软件设计模式不是标准,只是一个解决特定方案的相对合理化方案而已,解耦也不是软件设计的唯一标准,甚至不是最重要的标准。 1.4MVP模式的一般实现方式 目前我的项目中的实现方式是用接口来连接view和Presenter,根据定义好的接口来进行分块开发,如下图:
接下来是做一个小的demo来实际明确一下各部分的功能: 2.MVP的demo 2.1这个demo的具体使用场景和简单设计 我还是想把这个demo做成一个持续优化的项目,对于一个正式一点的项目,登录页面一般都是网站的第一步,这个demo就先做一个登录页面,暂时不考虑数据交互,MVP都定义最简单的形式,获取角色,输入用户名密码,登录。 2.2详细设计 分模块定义: 2.2.1 数据实体类项目(Data):添加角色类和用户信息类 2.2.2 数据业务逻辑模型项目(Model):添加一个登录验证类,添加获取角色信息和用户登录两个方法 2.2.3 界面业务逻辑操作项目(Presenter):这里有两部分的内容:1.接口定义;2.页面处理逻辑。通过定义委托和接口中的属性来控制页面上的事件和数据。 以前一直以为Model包括Data和Dao,所以一直不理解,为什么说Model和View没有通讯,实体类肯定是贯穿整个解决方案的,view就不说了。 2.3各个部分的实现
Data项目:
public class RoleInfo
{
public string RoleName { get; set; }
public string RoleID { get; set; }
}
View Code
public class UserInfo
{
public string RoleID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
View Code
Model项目:
/// <summary>
/// 权限管理
/// </summary>
public class Authority
{
/// <summary>
/// 初始化方法
/// </summary>
public IList<RoleInfo> GetRoleList()
{
IList<RoleInfo> roleList = new List<RoleInfo>();
roleList.Add(new RoleInfo() { RoleName = "管理员", RoleID = "1" });
roleList.Add(new RoleInfo() { RoleName = "操作员", RoleID = "2" });
roleList.Add(new RoleInfo() { RoleName = "一般用户", RoleID = "3" });
roleList.Add(new RoleInfo() { RoleName = "VIP用户", RoleID = "4" });
return roleList;
}
public bool Login(string userName, string password)
{
return true;
}
}
View Code
Presenter项目:
public delegate bool LoginEvnet(string userName,string password);
/// <summary>
/// 登录窗口需要实现的接口
/// </summary>
public interface ILoginView
{
IList<RoleInfo> RoleList { set; }
}
View Code
/// <summary>
/// 权限管理
/// </summary>
public class LoginPresenter
{
private ILoginView _view;
private Model.Authority authority;
public LoginPresenter(ILoginView view)
{
_view = view;
authority = new Model.Authority();
}
/// <summary>
/// 登录方法
/// </summary>
/// <param name="userName"></param>
/// <param name="password"></param>
/// <returns></returns>
public bool Login(string userName,string password)
{
return authority.Login(userName,password);
}
/// <summary>
/// 初始化方法
/// </summary>
public void Init()
{
_view.RoleList = authority.GetRoleList();
}
}
View Code
页面后台代码,负责绑定事件和更新页面控件属性:
public partial class LoginView : System.Web.UI.Page, ILoginView
{
private LoginPresenter presenter;
protected void Page_Load(object sender, EventArgs e)
{
presenter = new LoginPresenter(this);
presenter.Init();
btnLogin.Click += delegate {
if (presenter.Login(txtUserName.Value, txtPassword.Value))
{
//登录成功
this.ClientScript.RegisterStartupScript(typeof(string), "js", "alert('登录成功!');", true);
}
else
{
this.ClientScript.RegisterStartupScript(typeof(string), "js", "alert('登录失败!');", true);
}
};
}
public IList<RoleInfo> RoleList
{
set
{
foreach (RoleInfo text in value)
{
ListItem item = new ListItem();
item.Text = text.RoleName;
item.Value = text.RoleID;
ddlRole.Items.Add(item);
}
}
}
}
View Code
最后说一点,这周公司内部培训,接触了下struts2的框架,相比之下,突然觉得MVP只是一个概念,实际上用的时候并没有真正用到任何所谓的框架,MVP夹在MVC和MVVM之间感觉定位也是有点尴尬,就我目前的理解来说,MVP是一种关注代码分离的设计思想,还是不如MVVM分离的干净。
转载于:https://www.cnblogs.com/jinshizuofei/p/5061896.html