关于MVP的若干理解
时间:2010-11-18 来源:菜鸟老了
1、Model不与View交互
小喽啰(view)不应该有权限越级向老板(这家伙有权有势又有人脉)进行请求。若不然,当view有权限并频繁和Model交互时,领导层(Presenter,社团的管理层,替老板打工)对下级的管理能力将被减弱(view有了老板这层关系,持宠而娇)。并且最终将失去作用(手下小弟都不听他的话了)。此时,如果Model发生改变(股票跌了,老板破产,企业被收购),则view也被迫发生改变(一朝天子一朝臣,紧耦合),而presente则成了一个旁观则,换不换无所谓了。同理,当view发生改变(严打了,替老大背黑锅,进去了)时,Model必须进行相应的更改(必须收敛了,不然钱再多也没用)。
2、Model只负责相应Presenter的请求
理由:外行不管内行,老板的最大作用是选择正确的管理团队,并提供后勤支持。Model解除与View交互,并且根据presenter的决策提供资源(通过业务接口实现,presenter调用Model对外发布的接口而不是Model的所有资源)。
Presenter既有对view的控制权限,又不需要完全依赖于Model(Presenter这家伙有奶就是娘,谁能帮他实现理想(业务)他就跟谁)。这样即使Model内部发生改变,只需对外接口不变即可(家族再怎么内讧,只要发工资下面的人还是会继续跟着干的)。
3、View只对Presenter进行初始化注册和事件注册,不直接调用Presenter的方法。
新来的小弟(view)要在自己的直辖上司(presenter)那边进行登记,并且把自己的能力(event)和上司(presenter)说明(事件注册)。当view需要外出砍人的时候,向presenter说一声(event+),presenter 根据情况给view分配资源(event 相应),获得presenter的资源后view开始砍人(show);view 不应直接调用presenter中的方法(直接到老大的小金库里拿钱!!!!!!!!!不想活了)。
4、Presenter 响应View的请求,并调用IView中的方法。
这个道理和3 差不多,Presenter在得到view的请求后,根据view的能力(IView中定义的方法),直接指导view的工作(让你砍谁你就得去砍谁,谁叫你有能力)。
三者关系如下:
M:<-P M公开接口并响应P请求,但是不对P进行操作。
P:<=->:V P弱依赖于V而强控制V,V强依赖于P,并且对P无控制权,
V ∞ M V和M不可通讯。
以上为个人理解,欢迎大家交换意见,MVP又没最好,只有更好。
附:
Presenter
public class demoPresenter
{
private readonly IdemoView _view;
public demoPresenter(IdemoView view)
{
this._view = view;
InitForm();
}
private void InitForm()
{
//页面初次加载初始化
}
public void button1_Click()
{
throw new NotImplementedException();
}
}
View
public partial class demo : BaseForm, IdemoView
{
private static demoPresenter presenter;
private static demo _instance = null;
private static readonly Object ob = new object();
private demo()
{
InitializeComponent();
}
public static demo GetInstance()
{
if (_instance == null)
{
lock (ob)
{
if (_instance == null)
{
_instance = new demo();
presenter = new demoPresenter(_instance);
}
}
}
return _instance;
}
private void BaseForm_Closed(object sender, EventArgs e)
{
_instance = null;
}
private void BaseForm_Loaded(object sender, RoutedEventArgs e)
{
button1.Click += delegate { presenter.button1_Click(); };
button1.Content = "try";
}
public void show(string msg)
{
MessageBox.Show(msg);
}
}
public interface IdemoView
{
void show(string msg);
}
另一种Event的注册方法,不知道哪个比较好
public interface IdemoView
{
void show(string msg);
event EventHandler<RoutedEventArgs> clickEvent;
}
代码
private readonly IdemoView _view;
public demoPresenter(IdemoView view)
{
this._view = view;
InitForm();
}
private void InitForm()
{
//页面初次加载初始化
this._view.clickEvent += new EventHandler<RoutedEventArgs>(_view_clickEvent);
}