Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern for filtering objects

I have a List of objects which will be filtered.

This filtering will consist of at least 3 rules.

So for example :

public class Filtering {

List<MyObject> myObjectList;

List<MyObject> filterStep1(List<MyObject> myObjectList){

    for(Myobject myobj : myObjectList){
        if(isCriteriaSatisified){
            continue
        }
        else {
            removeThisObjectFromList
        }
    }
}


List<MyObject> filterStep2(List<MyObject> myObjectList){

    for(Myobject myobj : myObjectList){
        if(isCriteriaSatisified){
            continue
        }
        else {
            removeThisObjectFromList
        }
    }
}

}

I like this approach as it is simple, self contained and can see very easily what is trying to be achieved.

But perhaps there is a design pattern I should be using instead ?

The "Chain of Responsibility" pattern is something I'm considering where filterStep1 & filterStep2 in above code would be refactored into a seperate hander.

like image 384
blue-sky Avatar asked Sep 30 '14 13:09

blue-sky


2 Answers

This is the "pipes and filters" pattern, and while your implementation is okay, it's better not to hardcode the filtering logic in methods. Instead, write a Predicate<MyObject> for each of your boolean conditions (either the one built into Java 8 or the one from Guava). This is much easier to test and can easily be applied to existing clean APIs, such as the Streams API or Guava's collection views.

like image 112
chrylis -cautiouslyoptimistic- Avatar answered Sep 24 '22 01:09

chrylis -cautiouslyoptimistic-


One option using Java 8 streams:

myObjects.stream().filter( this::isCriteriaSatisified ).filter( this::anotherCriteria )

Assuming you have a method boolean isCriteriaSatisified(myObj) in your class. You can then collect that stream into another List.

like image 45
Andrejs Avatar answered Sep 21 '22 01:09

Andrejs