Introduction
The Essence Pattern provides a way to enforce users of an object to enter valid properties for that object. A full description of the pattern can be found in the original paper here (PDF). In this article, I shall provide a C# implementation of this pattern.
Background
If you are providing an external interface to your code either as an API or because your code forms a tier in an n-tier system, then the Essence Pattern can be used to force other programmers to put valid, required fields into an object before they start using that object. One common situation where this is required is for key fields to be saved to a database. The user of the object must not attempt to save that object to the database without the key properties, or the database will complain.
Of course, you could simply provide just one constructor that forces the programmer to enter all the required properties. In the simple case this is perfectly acceptable. However, if you are exposing an external interface, you may also want it to be COM wrappable. In this case, you can only have one, parameterless constructor which disallows that particular strategy. Also, what if there are a lot of required parameters, some of which need to be calculated or read from a data source? Are you going to make the user of your object store all these in local variables before they can construct your object?
The Example Code
The code sample with this article shows a very simple implementation of the Essence Pattern for a small class representing a contact. The Contact
class has 5 properties, three of which are required (FirstName
, LastName
and Email
), and two of which are optional (PhoneNumber
and PostalAddress
).
The first thing we do is create the ContactEssence
class as an internal
class of the Contact
class. The ContactEssence
contains only the required properties for the contact (FirstName
, LastName
and Email
), and allows read and write access to them all.
One of the two important methods of the ContaceEssence
is the Validate
method (shown below). This method essentially checks that all the required parameters are present and correct. Only when the Validate
method returns true
can the class advance to the next stage.
private bool Validate()
{
if (mFirstName.Length == 0)
return false;
if (mLastName.Length == 0)
return false;
if (mEmail.Length == 0)
return false;
else
{
System.Text.RegularExpressions.Regex emailReg =
new System.Text.RegularExpressions.Regex(
@"^[\w-]+(?:\.[\w-]+)*@(?:[\w-]+\.)+[a-zA-Z]{2,7}$",
System.Text.RegularExpressions.RegexOptions.CultureInvariant);
System.Text.RegularExpressions.MatchCollection results =
emailReg.Matches(mEmail, 0);
if (results.Count == 0)
return false;
}
return true;
}
The next stage is the creation of the real Contact
class, which is done through a call to the ContactEssence.
CreateContact
method.
public Contact CreateContact()
{
if (this.Validate() == true)
return new Contact(this);
return null;
}
As you can see, if the ContactEssence
is validated correctly, a Contact
is returned.
The final part of the puzzle is the Contact
class itself. The first area to look at are the constructors:
private Contact(ContactEssence xEssence)
{
mEmail = xEssence.Email;
mFirstName = xEssence.FirstName;
mLastName = xEssence.LastName;
}
The constructor is private. ContactEssence
is an internal class to the Contact
, so it has access to the private constructor. This means that the Contact
class can only be created by the ContactEssence
class.
When the Contact
is created from the ContactEssence
, it simply copies all the required fields. Additional (optional) fields are left in their original initialised state.
Finally, in the Contact
class, the required fields are exposed as read-only properties, while the optional fields are read-write. This means that once the required fields are created, they cannot be changed.
So how do we use the Contact
class?
The example code shows the role of the ContactEssence
and the validation of required Contact
properties:
Contact.ContactEssence essence = new Contact.ContactEssence();
essence.Email = "me@mydomain.com";
Contact invalidContact = essence.CreateContact();
if (invalidContact == null)
Console.WriteLine("Created NULL contact!");
essence.FirstName = "Dermot";
essence.LastName = "Gubbins";
Contact validContact = essence.CreateContact();
if(validContact == null)
Console.WriteLine("Oops! This should be valid!");
else
{
validContact.PhoneNumber = "(+44) 444 444";
Console.WriteLine("\nContact Created ...\n");
Console.WriteLine(validContact.ToString());
}
Points of Interest
As explained in the original paper the Essence Pattern can be used in object creational patterns to create multiple valid classes by changing one or more of the required fields and then creating a new instance of the main class. Additionally, the Essence can also act as a builder class.