Domain Objects: The Importance of State
November 13, 2010 Leave a comment
When I stoked up Windows Live Writer, my intent was to write an entry about testing. Specifically, I was going to aim at testing the domain. Then I realized I had never written an entry on domain objects and thought it was a necessary place to start.
As a disclaimer, this article is not the be all, end all of explanations of domain modeling. If you want a full treatise, you would be best reading Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans. If you want to stick in the .NET world, Applying Domain Driven Design and Patterns by Jimmy Nilsson is also a good read.
What is a Domain?
Now this is the thousand dollar question. What is a domain? Rather than answer the question straight out, let’s look at a scenario. Picture a company that takes orders via phone (or Internet, if phone orders seem antiquated). There is an application to take an order, another to box the items in the warehouse and a third to ship the items to the customer.
If we look at this scenario from the database, we might see a schema much like the one below.
|
Above taken from Adventure Works, SQL Server 2008 R2
Now, if we take the schema above, we can build each of the applications by mirroring the schema as objects in the applications. This is acceptable, but not optimal. In addition, we are potentially exposing sensitive customer data, like payment information, to employees who have no need to see the information.
Let’s talk about a customer for a second. In the ordering application, all of the customer information is important. We need to know the customer’s name, address or addresses (if there are different home, credit card and shipping addresses, for example), at least one telephone, and at least one form of payment information. This application may be served well by simply mirroring the database schema. In other words, in the order “domain”, we need all types of information about a customer.
When we move to the shipping domain, however, we only need a name, phone number and shipping address. The customer object may be better set up like the following C# code:
public class Customer
{
public string Name { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
}
In the warehouse domain, we don’t really need to have a customer object at all, as we simply need to pick some items and put them in a box. To aid the application in the shipping domain, we can print out a order label that can be scanned.
In the above example, there is one application per domain, but we can have multiple applications in a single domain. We can, theoretically, have applications that cross multiple domains, but that is a concept beyond this post.
Now we can return to the question: What is a Domain? A domain is a specific area of influence for an application. In my examples, I use the idea of an order domain, a warehouse domain and a shipping domain. Perhaps a weak example, but it shows that an object can radically change from the expected object in a relational database. And that is worth the price of admission (currently free).
Creating Domain Objects
In general, a domain object is an object that holds state. While there are patterns, like Active Record, that have “smart” objects that contain behavior, the norm for the domain are containers that hold current information about an object, or its current state. The repository pattern, which separates behavior and state, is much more common today.
To put it in a way that jogs memory, just think of BS. Domain objects deal with the S (state) in BS (behavior and state) and not about the B (behavior).
Since we are only dealing with state, it is extremely easy to make our domain objects, as we can use the simple property format:
public class ObjectType
{
public Type PropertyName { get; set; }
}
When I start a new project, the first folder I create is the domain folder. I then set up two projects, one for domain objects and another for domain specific exceptions. I will then determine whether or not to test the domain objects, which is the subject of the next post. The Visual Studio project will look something like this:
I will cover more of the project setup I use in future posts.
Important Points
- A domain is an area of influence. When we develop an application, we need to find the Subject Matter Expert (SME) in that domain and have them help us determine the domain objects.
- Domain objects handle state and do not deal with behavior.
- Domain objects should be a primary or “first” concern when developing an application.
See you at the next post, which covers the question “should I set up tests on domain objects?”
Peace and Grace,
Greg
Twitter: @gbworld