Tuesday, January 24, 2006
Use delegates to replace repeated guard clauses
When working with Presentation Model a recurring source of pain is the isLoading guard clause. The isLoading guard is required on the Reload method. Despite not being required, I also prefer to have my setting methods guarded. If you choose not to guard setting methods the last changed value will be set in the Presentation Model twice (once where you set it and once when Reload raises the XChanged event).
For example:
You can solve this issue by extracting the setting code into it's own method, creating a delegate to this method, and passing the delegate to the Reload method. The reload method can first set the value of isLoading and then execute the delegate.
For example:
class FooView...As the number of data elements on the screen increases so does the annoyance with repeating the isLoading guard.
FooView(FooPM pm)
{
this.pm=pm;
Reload();
}
...
private TextBox barTextBox;
private FooPM pm;
private bool isLoading=false;
...
public void Reload()
{
if (!isLoading)
{
isLoading=true;
barTextBox.Text=pm.BarText;
isLoading=false;
}
}
public void barTextBox_TextChanged(object sender, EventArgs e)
{
if (!isLoading)
{
pm.BarText=barTextBox.Text;
Reload();
}
}
}
You can solve this issue by extracting the setting code into it's own method, creating a delegate to this method, and passing the delegate to the Reload method. The reload method can first set the value of isLoading and then execute the delegate.
class FooView...The resulting code is one method longer, but removes the isLoading repetition.
...
public void Reload(SetDelegate setMethod)
{
if (!isLoading)
{
isLoading=true;
setMethod();
barTextBox.Text=pm.BarText;
isLoading=false;
}
}
public void SetBarText()
{
pm.BarText=barTextBox.Text;
}
public void barTextBox_TextChanged(object sender, EventArgs e)
{
Reload(new SetDelegate(SetBarText));
}
}


