0

I have a requirement where I get a list of objects say List.

Now I have filter Criteria which I need to apply to filter out the objects in the list.

Currently I am thinking of using chain of responsibility.

So my criteria could be say, Blacklisted names, whitelisted names etc.. So if an object contains name which is blacklisted I need to remove it from the final list.

Please suggest which pattern is suitable for this problem.

  • 3
    Ok, so you are going to use a filter chain. What is the question? – user40980 Apr 10 '15 at 15:12
  • To the extent that each item on the list can be processed individually (i.e. the decision on one item do not affect the decision of another item), you can think of it as a logical function applied to each item without concerning other items. Furthermore, the logical function can typically be treated as a decision tree. If the decision tree is lopsided (like a list), then yes, it seems that chaining them up may be the good approach. Decisions that are not like a list will be like linear weighting of factors, neural networks or SVM, etc. – rwong Apr 11 '15 at 4:58
  • The question of "should my logical filtering function be applied to one item at a time, or one list at a time?" depends on a lot of factors. If your list is large (say, mega-millions of items), it may make sense to consider performance as one of the factors. But otherwise, the ease of maintenance (in particular allowing anyone to change the logic without breaking things) will usually take priority. – rwong Apr 11 '15 at 5:01
  • Another consideration is the persistence (storing, loading and editing) of those rules. If those rules will be hard-coded then the issue of design is not as important. If they must be configurable, then you will need to use OOP techniques (including design patterns) to represent the structure of the logical function by mirroring it with the structure of a bunch of objects. – rwong Apr 11 '15 at 5:06
  • If the platform you use allows you to save, load and execute small snippets of code, and if there is no security concern, you may consider the easy route because the code snippet will then be the format of persistence - no need for objects. However, this approach carries great security risk, because arbitrary malicious code could have been injected into the configuration file and will be executed. – rwong Apr 11 '15 at 5:08
0

At this very phase of development you describe, I wouldn't recommend looking for a certain pattern and implement it. Just as a first step, collect what you know:

  • You need to filter
  • You know certain criteria
  • You have an object list of type List
  • You would like to have (I assume) a new listFiltered of the same Type List.

Now it depends what libraries and what language you work with. One could think of a finished library method that takes a list of type List and applies a user defined filter function to return a filtered copy. Or maybe there is a special kind of iterator (or cursor) available that takes a filter argument, iterates and returns only the suitable items by skipping the not suitable ones.

So my second step I recommend is looking if somebody has solved the same problem, by using a library function or maybe she/he has noted a snippet. Also, it could be that you solved a similar problem earlier. It could be useful to adopt what you have written earlier.

If you don't find anything like this, then my recommendation as third step would be to implement straightforward what you need. It could look like this (all code is pseudocode):

class MyTools {
    ...
    List filterList(list, filterCriteria) ... 
    ...
}

or:

class ListHelper {
    ...
    List filter(list, filterCriteria) ...
    ...
}

Some draft discussion base for the filter function (pseudocode):

List filter(list, criteria) {

    List result = new List();
    foreach (item in list) {
       if (this.criteriaMatches(item, criteria)) {
          result.add(item);
       }
    }

    return result;
 }

By drafting that way, you'll learn that you need some "criteriaMatches()" method, and you will realize that you should think about referencing or cloning, and possibly deep or shallow cloning, and how to test the whole bunch, and if some code should be synchronized, etc. These are the relevant questions now.

According to my experience, you cannot save time by "predicting" the right pattern, because reality and also code development is too chaotic. It is better to be prepared to constantly adjust and refactor the code structure in a well ordered and alert manner.

So, later it could be that you would migrate your code written today into a final Tools-Class. Or it could be that you will drop it and write a special iterator, because your team would benefit from doing so. Only the larger perspective will make clear what pattern really is useful, maybe decided by your team.

Finally, the "chain of responsibility" as you mentioned, is a pattern in that a list of acting objects can be enhanced by adding new objects. An argument to work is fed into the list, and the suitable object in the list will decide: "This object is my responsibility, I'll work this object." You could try to think around ten corners to see such a chain in a simple filter. But this will produce more work later than just straightforward implementing the solution. For the task described, it is an overhead.

  • For simplicity appraoch looks fine. I am also thinking of not wasting more time in design initially but the problem look very similar to chain of responsibility and If I could used it from start then It can benefit me later. – behinddwalls Apr 12 '15 at 7:36
  • I understand your considerations. Finally, listen to your guts :-) you may also implement your pattern just to collect experience, this is very helpful. However, I observe that 1) this "later" not often really comes true, and 2) if I look a level deeper, such similarities you mention often vanish. That's why I am so reluctant :-) – peter_the_oak Apr 12 '15 at 18:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.