事件处理中的MVP模式
本文关键字:模式 MVP 事件处理 | 更新日期: 2023-09-27 17:58:27
我刚开始使用C#和MVP设计模式。当涉及到事件处理时,我对具体的实现表示怀疑。我知道,视图不应该知道演示者,演示者应该通过视图界面控制视图。
假设我有两个文本框,希望检查是否有错误。如果发生错误,我想更改文本框文本属性。创建一个EventHandler并使用sender对象来验证用户当前使用的文本框是否错误?
类似于:
IView:
interface IMainView
{
event KeyPressEventHandler KeyPressed;
}
视图:
public partial class MainView : Form, IMainView
{
public frmInterakcija()
{
InitializeComponent();
this.textBox1.Name = "textBox1";
this.textBox2.Name = "textBox2";
new MainPresenter();
Bind();
}
private void Bind()
{
this.textBox1.KeyPress += KeyPressed;
this.textBox2.KeyPress += KeyPressed;
}
}
演示者:
class MainPresenter
{
private IMainView _view;
public MainPresenter(IMainView view)
{
_view = view;
this.initialize();
}
public void initialize()
{
_view.KeyPressed += _view_textBoxKeyPressed;
}
public void _view_textBoxKeyPressed(object sender, EventArgs e)
{
if (sender.GetType() == typeof(TextBox))
{
TextBox textBox = (TextBox)sender;
if (textBox.Name.Equals("textbox1")
{...} // Do validation/changes on textbox1
else ...
}
}
}
或者,我应该为我拥有的每个文本框创建事件处理程序,并通过属性更新/处理错误?(我想这会使我的代码变得多余)
什么是正确的方法?
IMHO presenter
应该不知道视图特定的对象(代码中的示例textbox
)。这种逻辑不应该出现在演示者中。演示者一定不知道UI中控件的ID,这更糟糕。记住,这样做的好处之一应该是,您可以通过模拟视图来测试演示者,如果您有特定于UI的代码,则无法对演示者进行单元测试。
对我来说,这确实像是两个不同的events
,因为你在做不同的逻辑。我会提出两个不同的events
,一个进行验证,另一个进行自己的逻辑。演示者不必检查发件人是textbox
还是textbox
的id。此外,如果您有另一个文本框,那么在当前实现中需要另一个if条件。
此外,在视图中,它应该是new MainPresenter(this);
演示者绝对不应该有视图特定的类型(例如控件、事件等),因为在测试演示者的逻辑时,这些类型很难伪造。相反,你应该有如下的东西。
IView:
interface IMainView
{
// give these better names based on what they actually represent (e.g. FirstName and LastName)
// you could also add setters if you needed to modify their values from the presenter
string Text1 { get; }
string Text2 { get; }
// provide a way to bubble up validation errors to the UI
string ErrorMessage { get; set; }
}
演示者:
class MainPresenter
{
private IMainView _view;
public MainPresenter(IMainView view)
{
_view = view;
}
public void ValidateText1()
{
if (/* some validation is false */)
{
_view.ErrorMessage = "Text1 isn't valid";
}
}
public void ValidateText2()
{
if (/* some validation is false */)
{
_view.ErrorMessage = "Text2 isn't valid";
}
}
}
视图:
public partial class MainView : Form, IMainView
{
var readonly MainPresenter _presenter;
public frmInterakcija()
{
InitializeComponent();
_presenter = new MainPresenter(this);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs eventArgs)
{
_presenter.ValidateText1();
}
private void textBox2_KeyPress(object sender, KeyPressEventArgs eventArgs)
{
_presenter.ValidateText2();
}
#region Implementation of IMainView
public string Text1
{
get { return textBox1.Text; }
}
public string Text2
{
get { return textBox2.Text; }
}
public string ErrorMessage
{
get { return labelErrorMessage.Text; }
set { labelErrorMessage.Text = value; }
}
#endregion
}