MVP全称:Model-View-Presenter ;MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
如果你经常使用MVC,可能会不理解MVP,MVP用在安卓开发,桌面开发比较多。对于Model和View层,它们和MVC没什么区别。但是对于Presenter:
一个View页面/界面,我们都会安排一个Presenter,页面和Presenter相互关联。如何相互关联呢?
一般我们会在UI层定义一个接口类,这个类包括我们页面的一些属性和行为,比如文本展示,点击事件等。而我们的Presenter会实现这些接口,并和UI对象绑定,UI的任何行为都将与Presenter里的方法绑定在一起,UI点击行为会触发Presenter根据接口所实现的行为方法。
下面是MVP模式在窗体应用程序中的使用:参考
做过.net的winform和WPF开发的可能很好理解这个过程。
第一步,给每个view窗体,约定好一个接口
public interface IMemoFormView {
String Title { get; set; }
String Summary { get; set; }
String Location { get; set; }
String Tags { get; set; }
DateTime BeginWithin { get; set; }
DateTime DueBy { get; set; }
String Message { get; set; }
Int32 GetSelectedPriorityValue();
void FillPriorityList(Int32 selectedIndex);
Boolean Confirm(String message, String title);
void SetErrorMessage(String controlName);
}
第二部,视图类实现约定的接口,实现接口。
public partial class MemoForm : Form, IMemoFormView {
public string Title {
get { return memoForm_Text.Text; }
set { memoForm_Text.Text = value; }
...
}
public DateTime DueBy {
get { return memoForm_DueBy.Value; }
set { memoForm_DueBy.Value = value; }
}
public int GetSelectedPriorityValue() {
var priority =
memoForm_Priority.SelectedItem as PriorityItem;
if (priority == null)
return PriorityItem.Default;
return priority.Value;
}
public void FillPriorityList(int selectedIndex) {
memoForm_Priority.DataSource =
PriorityItem.GetStandardList();
memoForm_Priority.ValueMember = "Value";
memoForm_Priority.DisplayMember = "Text";
memoForm_Priority.SelectedIndex = selectedIndex;
}
public void SetErrorMessage(string controlName) {
var control = this.GetControlFromId(controlName);
if (control == null)
throw new NullReferenceException(
"Unexpected null reference for a form control.");
memoForm_ErrorManager.SetError(control,
ErrorMessages.RequiredField);
}
...
}
第三步,窗体类初始化时创建Presenter对象,并将自己传递给Presenter,此时窗体创建的时候就和Presenter绑定起来了。
public partial class MemoForm : Form, IMemoFormView
private MemoFormPresenter presenter;
public Form1() {
// Framework initialization stuff
InitializeComponent();
// Instantiate the presenter
presenter = new MemoFormPresenter(this);
// Attach event handlers
...
}
private void MemoForm_Load(
object sender, EventArgs e) {
presenter.Initialize();
}
...
}
第四步,Presenter类在初始化的时候会拿到我们实现的窗体对象memoForm
public class MemoFormPresenter {
private readonly IMemoFormView view;
public MemoFormPresenter(IMemoFormView theView) {
view = theView;
context = AppContext.Navigator.Argument
as MemoFormContext;
if (_context == null)
return;
}
public void Initialize() {
InitializeInternal();
}
private void InitializeInternal() {
int priorityIndex = _context.Memo.Priority;
if (priorityIndex >= 1 && priorityIndex <= 5)
priorityIndex--;
else
priorityIndex = 2;
if (_context.Memo.BeginDate.HasValue)
_view.BeginWithin = _context.Memo.BeginDate.Value;
if (_context.Memo.EndDate.HasValue)
_view.DueBy = _context.Memo.EndDate.Value;
_view.FillPriorityList(priorityIndex);
_view.Title = _context.Memo.Title;
_view.Summary = _context.Memo.Summary;
_view.Tags = _context.Memo.Tags;
_view.MemoLocation = _context.Memo.Location;
}
...
}
这样,页面初始化,我们会经过Presenter的InitializeInternal,将数据set到对应view所绑定的UI字段上。