Applying Arbitrary Custom Filters To A Collection: Chain Of Responsibility
I faced some annoyance of my Randomized Blogroll Plugin the last days: My own blogroll contains some subscriptions to ego searches that I don’t want to publicize on my webpage, since they are
- depressing, and
- not of any public interest.
Getting tired of removing them by hand everytime I update my blogroll, I started to implement filtering. Here’s what I came up with. See my mind at work.
My first sketch was to create a simple class called Filter, containing just one function that gets passed a collection, iterates through it and does what needs to be done. This is PHP 4.x code:
However, if I want to apply an additional filter (renaming root category “Subscriptions” to “General”, for example), the collection is stepped through a second time: ugly.
So the next step was to extract the iteration from Filter and move it into the collection class:
However, this doesn’t solve the problem of applying more than one filter, since collection->filter() still only takes one Filter instance. Maybe I should make it accepting an array, too?
No. There is a nice little design pattern at hand that solves this problem: chain of responsibility. This pattern can be applied if
the set of objects that can handle a request should be specified dynamically.
This is excatly what I want to do. Applying this pattern the collection can be left untouched, while I extend the Filter class:
The code is simple. FilterChain delegates filtering to doFilter() which would be virtual protected in C++ or comparable languages. appendToChain() find the last member of the chain and sets its next element property.
The usage is simple, too:
Reflecting the state of affairs for this plugin, I have customizable input, customizable output, customizable filtering and I’m starting on customizable sorting. Maybe it neds some renaming? What about The most customizable blogroll plugin ever?