Our Customer comes to us and likes what we have done setting up a way for them to find if a customer is active, but now they want to keep track of all the customers. We come up with the concept of a Customer Record Book and our client seems happy with that:
[Test]
public void ShouldBeAbleToCreateACustomerRecordBook()
{
IList<Customer> recordBook = new List<Customer>();
recordBook.Add(new Customer(new DateTime(2007, 04, 29), "Steven", "Rockarts"));
recordBook.Add(new Customer(new DateTime(1965, 04, 29), "John", "McCarthy"));
recordBook.Add(new Customer(new DateTime(2006, 04, 29), "Doug", "Armstrong"));
CustomerRecordBook customerRecordBook = new CustomerRecordBook(recordBook);
Assert.IsNotNull(customerRecordBook);
}
public class CustomerRecordBook
{
private IList<Customer> customerList;
public CustomerRecordBook(IList<Customer> customerList)
{
this.customerList = customerList;
}
}
Our record book does its job of storing customers well but our client wants us to add a way to find all the active customers in it. Our first attempt at creating a way to find all the active customers looks like this:
[Test]
public void ShouldFindAllActiveCustomers()
{
IList<Customer> recordBook = new List<Customer>();
recordBook.Add(new Customer(new DateTime(2007, 04, 29), "Steven", "Rockarts"));
recordBook.Add(new Customer(new DateTime(1965, 04, 29), "John", "McCarthy"));
recordBook.Add(new Customer(new DateTime(2006, 04, 29), "Doug", "Armstrong"));
CustomerRecordBook customerRecordBook = new CustomerRecordBook(recordBook);
Assert.AreEqual(1, customerRecordBook.Filter(new ActiveCustomerSpecification()).Count);
}
public class CustomerRecordBook
{
private IList<Customer> customerList;
public CustomerRecordBook(IList<Customer> customerList)
{
this.customerList = customerList;
}
public IList<Customer> Filter(ActiveCustomerSpecification specification)
{
IList<Customer> list = new List<Customer>();
foreach (Customer customer in customerList)
{
if(customer.IsAnActiveCustomer(specification))
list.Add(customer);
}
return list;
}
}
The Filter method that we just created takes in the ActiveCustomerSpecification, creates a temporary list and then iterates through the customer list adding the active customers to the temporary list, once it is done it returns the temporary list. Our test passes but there are a couple of improvements we can make to this code. First of all, we don't need to create a temporary list or use an IList<Customer> we can leverage the yield keyword and IEnumerable<Customer> to make our code tighter:
public IEnumerable<Customer> Filter(ActiveCustomerSpecification specification)
{
foreach (Customer customer in customerList)
{
if (customer.IsAnActiveCustomer(specification))
yield return customer;
}
}
This change will break our test since IEnumerable does not contain a definition for count. If we look at the available constructors for the List class we can see that List has a contructor for creating a list from IEnumerable. So we can easily fix our test:
[Test]
public void ShouldFindAllActiveCustomers()
{
IList<Customer> recordBook = new List<Customer>();
recordBook.Add(new Customer(new DateTime(2007, 04, 29), "Steven", "Rockarts"));
recordBook.Add(new Customer(new DateTime(1965, 04, 29), "John", "McCarthy"));
recordBook.Add(new Customer(new DateTime(2006, 04, 29), "Doug", "Armstrong"));
CustomerRecordBook customerRecordBook = new CustomerRecordBook(recordBook);
Assert.AreEqual(1, new List<Customer>(customerRecordBook.Filter(new ActiveCustomerSpecification())).Count);
}
Now we are able to find all active customers in a list.