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:
class FooView...
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();
}
}
}
As the number of data elements on the screen increases so does the annoyance with repeating the isLoading guard.

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...
...
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));
}
}
The resulting code is one method longer, but removes the isLoading repetition.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.