Strongly-Typing Your Domain Values
I love this one. I don’t know the name of the pattern, but i love using it.
Imagine your system uses strings to represent the value of a status field. potential values of this field are:
- New
- Requested
- Open
- Closed
- Deferred
- In Progress
- More Information Required
…and you want to write a method (or webservice) called UpdateStatus, which takes in one of these values.
Standard signature would look something like this:
public void UpdateStatus(string newStatus)
The use of “string” for the static type has the problem that someone could pass through a rubbish value as a string, and the UpdateStatus method is now responsible for domain validation of the input.
However, following the pattern below, you’re able to statically define your domain (if known at design-time) and enforce the stronger type in subsequent method calls.
public class IssueStatus
{
void IssueStatus(string description)
{
this.description = description;
}
readonly string description;
public static IssueStatus New = new IssueStatus("New");
public static IssueStatus Requested = new IssueStatus("Requested");
public static IssueStatus Open = new IssueStatus("Open");
}
and you can then use the strong IssueStatus type in your signatures:
public SaveButton_Clicked(object sender, EventArgs e)
{
bo.UpdateStatus(IssueStatus.New);
}
public void UpdateStatus(IssueStatus newStatus)
{
if (newStatus == IssueStatus.New)
{
// do something here
}
}
I learnt this one on the job a few years back, and think it’s fantastic.
Related posts:
- XPath – Selecting distinct (unique) values Its been a while since I’ve last posted. I’ve...
- Covariance and Contravariance Covariance and Contravariance are terms used in programming languages and...
- Happy Birthday (The C-Sharp way) This evening I wanted to wish someone a happy birthday....
- Thread Safety and Locking I was recently reading a post about writing non-threadsafe code...
- Upgrading Database Schema’s in .NET This post is the first what I intend to be...
We found a related refactoring to this recently which I thought was really cool.
Say you want to add a new status called Imported for issues which are newly added, but came from some other database instead of being added by hand.
So you change your code from:
if (newStatus == IssueStatus.New)
{
// send a “new issue created” email
}
To:
if (newStatus == IssueStatus.New || newStatus == IssueStatus.Imported)
{
// send a “new issue created” email
}
Then you find some other place in the code that also needs to change:
if (newStatus == IssueStatus.New)
{
// create a record in the issue billing system
}
…becomes:
if (newStatus == IssueStatus.New || newStatus == IssueStatus.Imported)
{
// create a record in the issue billing system
}
That conditional expression for the if statements is duplicate code!
So if you’ve used a strong type IssueStatus, instead of a string, you can easily add a property to your IssueStatus class:
public bool IsNewlyCreated { get; }
// make it true for New and Imported, false otherwise
Then refactor to:
if (newStatus.IsNewlyCreated)
{
// whatever
}
Suddenly your if statements become much more expressive about _why_ the code block should be run. If we choose the property names well, then the code is not just saying “if status is X or Y”, it’s telling you the business meaning behind it. And if we choose the property names well, we should be able to come along in future and add a new status called Z, set its properties appropriately, and existing code will already understand it.