Description
When designing an application you must think about the scalability of the application itself and of the modules you are creating. The example below show how I designed a simple filtering system and took advantage of the interface power.
For the filtering system i created an interface that is inherited both by a filter type and a collection of filters. In this way it doesn’t matter to the end user if he has one item or a collection, he will make a validation in the same way.
public interface IFilter<T>
{
bool Pass(T element);
}
public class Filter<T> : IFilter<T>
{
Predicate<T> filterFunction { get; set; }
public Filter(Predicate<T> filterFunction)
{
this.filterFunction = filterFunction;
}
public bool Pass(T obj)
{
return filterFunction.Invoke(obj);
}
}
public class FilterGroup<T> : IFilter<T>
{
private List<IFilter<T>> Filters { get; set; }
public FilterGroup()
{
this.Filters = new List<IFilter<T>>();
}
public FilterGroup(params IFilter<T>[] filters)
{
this.Filters = filters.ToList();
}
private void Add(IFilter<T> filter)
{
this.Filters.Add(filter);
}
public bool Pass(T element)
{
return this.Filters.All(x => x.Pass(element));
}
}
Now let’s test this functionality. Define a base class Person and then define the following filters:
- A simple filter
- A filter group that combines 2 filters
- A mixed filter that combines 1 filter and 1 filter group
public class Person
{
public string Name { get; set; }
public string City { get; set; }
public int Age { get; set; }
public Person(string name, int age, string city)
{
this.Name = name;
this.Age = age;
this.City = city;
}
}
this.Persons = new List<Person>
{
new Person("John", 21, "New York"),
new Person("John", 22, "Sydney"),
new Person("Bob", 18, "Cairo"),
new Person("Morgan", 18, "Fukushima"),
new Person("Kayla", 18, "Beirut"),
new Person("Mark", 50, "Mumbai")
};
IFilter<Person> filterAgeUnder50 =
new Filter<Person>((p) => p.Age < 50);
IFilter<Person> filterNameNotJohn =
new Filter<Person>(p => p.Name != "John");
IFilter<Person> filterCombined =
new FilterGroup<Person>(filterAgeUnder50, filterNameNotJohn);
IFilter<Person> filterNotInCairo
= new Filter<Person>(p => p.City != "Cairo");
IFilter<Person> filterNested =
new FilterGroup<Person>(filterCombined, filterNotInCairo);
filteredPersons1 =
Persons.Where(p => filterAgeUnder50.Pass(p))
.ToList();
filteredPersons2 =
Persons.Where(p => filterNameNotJohn.Pass(p))
.ToList();
filterPerson3 =
Persons.Where(p => filterCombined.Pass(p))
.ToList();
filterPerson4 =
Persons.Where(p => filterNested.Pass(p))
.ToList();
Result










