It is true what they say about design patterns that they are simply the embodiment of techniques already in general use. I have been using the Active Record Pattern since 1985.
One of the attributes of this pattern is the use of static members in the implementation to perform searches that return collections of the underlying data.
class Customer {
static Customer FindCustomerById( int Id ) { ... }
static Customer[] FindActiveCustomers() { ... }
}
In many cases where I need much more flexibility I break encapsulation and include a method such as
static Customer[] FindCustomers( string criteria ) { ... }
where one would call it as
Customer[] customers = Customer.FindCustomers( "LastName = 'Smith'" );
Of course this is a hold over from when I used this pattern in C, is clearly not a best practice, and in the wrong hands can lead to SQL injection and other problems.
Is there a suitable pattern or practice that could be applied that would allow the Customer class to become a "criteria" for such a search?
For example suppose I want to find customers whose last name was Smith, I might consider writing an implementation such as:
static Customer[] FindCustomers( Customer customer ) { ... }
to be called as (with the appropriate constructor of course):
Customer[] customersnamedsmith =
Customer.FindCustomer( new Customer( "Smith" ) );
Or is it better to create a co-class that would define the criteria?