When designing object-oriented systems, often the approach
to designing the objects is to use domain or business objects containing
properties and methods related to the underlying data. There are various
schools of thought about how to do this, and whether to use objects at all,
instead of some of the built-in objects to .NET. Rather than get into that
discussion, this section will be using the domain object concept for designing
application systems.
An object is created in some way. For instance, an object
is created new, meaning that a new instance of an object is created. At this
point, it would be considered "dirty", meaning it hasn't been
uploaded to the underlying data source (database, XML, text file, or some other
source). The data source doesn't know anything about that data, and it
shouldn't know anything about the data source (at any time). Upon saving it to
the repository, it would be considered "clean" in that it doesn't
contain any changes from what the data source knows it to be. However, upon
changing the properties of an object, this object would be considered
"dirty" again because it contains changes from what the underlying
data source knows it to be.
What is the means to track changes? As shown with the
previous code example above, IDomainEntity describes an IsDirty property that
tracks whether the object is dirty. The methods change the value of that
property internally based on whether any changes were made. It may seem
obvious to make IsDirty writable and assign the value directly, but I like this
indirection better. It makes the actions more clear, to set the dirty value of
the property or to clear it. Making the property writable could mean an accidental
mistake of setting it to true when it was meant to be false, which is harder to
do with method declarations. The following is an example of a property:
Listing 6
public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
this.SetDirty();
}
}
}
The property above only sets the dirty flag if the name
property value changed from what it existed previously. If you have a
repository that is a collection of IDomainEntity objects, then in your
repository, it is possible to have a method as below:
Listing 7
public virtual int SaveChanges()
{
int savedItems = 0;
foreach (T item in this.Items)
{
if (item.IsDirty)
{
this.SaveItem(item);
item.ClearDirtyStatus();
savedItems++;
}
}
return savedItems;
}
This method would then call the SaveItem method to perform
the actual storage of the item data. It is possible to take this more in-depth
in creating a repository that works with a business object.