Challenge
You have a list of objects with the following class structure:
public
class
Member
{
public
string
Name;
public
DateTime
DateOfBirth;
}
You need to do an operation of selecting all Members who have an age greater
than 18.
One way is to add a new property called IsAboveEighteen and
set the value by iterating over the items and comparing with current date. But
this requires more processing.
We can achieve the same using Visitor pattern by adding a property which
operations on the existing properties and returns the value.
Definition
"Represent an operation to be performed on the elements of an object
structure. Visitor lets you define a new operation without changing the classes
of the elements on which it operates."
Implementation
Introducing a new property named IsAboveEighteen and in the getter
implement the code to read Date-Of-Birth property to calculate the value.
public
class
Member
{
public
string
Name;
public
DateTime
DateOfBirth;
public
bool
IsAboveEighteen
{
get
{
bool
result = (DateTime.Now
-
this.DateOfBirth).TotalDays
> 365 * 18;
return
result;
}
}
}
In the above example, the new property explores the existing property
values to calculate its own value. The advantage is that there is no change of
structure and no extra operations to achieve the desired result.
The following unit tests operate on the new property and display the
result having IsAboveEighteen as true.
[TestMethod()]
public
void
IsAboveEighteenTest()
{
IList<Member>
list =
new
List<Member>()
{
new
Member()
{ Name =
"N1",
DateOfBirth=
new
DateTime(2000,
1, 1)},
new
Member()
{ Name =
"N2",
DateOfBirth=
new
DateTime(2000,
1, 1)},
new
Member()
{ Name =
"N3",
DateOfBirth=
new
DateTime(1990,
1, 1)},
new
Member()
{ Name =
"N4",
DateOfBirth=
new
DateTime(1980,
1, 1)}
};
var
selectedList = list.Where(m => m.IsAboveEighteen);
foreach
(Member
member
in
selectedList)
Console.WriteLine(member.Name);
Assert.AreEqual(2,
selectedList.Count());
}
On running the test we can see the following output.
Extending Visitor in Sql Server
In Sql Server the same functionality can be achieve using Computed
Columns. Even though Vistor Pattern is an Object Oriented Extension we can use
the concept in database too.
Let us explore this with a simple example. We are having a table to store
Transaction having Quantity and Price. The table is populated with data. We need
to get the TotalPrice which is Quantity multiplied by Price. Without doing any
data updating we can use Computed Column as shown below to achieve the results.
The result is shown below:
The above result is achieved without doing any data updating.
Summary
In this article we have explored the Visitor pattern. It allows us to be
add more functionality without doing much change in the structure. Keeping this
pattern in mind often helps in a better way of architecting.