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