Sebastián Grignoli
Sebastián Grignoli

Reputation: 33432

What's the name of this pattern?

I'm writing a spec in which I want to state (in an unambiguous way) that the programmer use this pattern:

We have to apply several filters to the data we are processing. The configuration allows the creation of those filters. There can be several of them, or none. I don't want that logic in the exporting class (because it could grow large in the future, with different kind of filters that we cannot foresee now). I want them to run one after the other, so I'm going to ask for a method in the exporting class: "addFilter", that should store the objects in an internal array, and then have them executed when the actual exporting process runs.

I don't know if the question is clear enough. It's like a chained strategy, but not exactly a strategy because it's not mandatory to have a filter at all.

Again, the question is: How should I call this pattern in the specs?


Edit: An example of what I'm trying to do:

$report = new Report();
$report->addFilter(new RemoveSpaces())
       ->addFilter(new SubstituteText($predefined_substitutions_array)
       ->addFilter(new FixCapitals())
       ->addFilter(new Encode("utf8"));
echo($report->generate());   // filters are actually used during generation.

Supposedly, the user should be able to decide whether to RemoveSpaces or not, what text to substitute, whether to capitalize words or not, what encoding to use, etc. Some filters will surely be added in the future on user (client, actually) request.

Once factored, the filters should have a simple interface that the report would call:

foreach($this->filters as $current_filter) {
  $data = $this->filters[$current_filter]->applyTo($data);
}

Upvotes: 0

Views: 309

Answers (4)

tcarvin
tcarvin

Reputation: 10855

I would actually say you did not include enough code to determine which pattern could be used to acheive your objective, because you did not show some sample code or signatures of your Filter class.

How does your Report class interacts with the Filter class (or vice versa)?

I don't think its a classic Chain of Responsibility becasuse in that case each participant is responsible for calling the next particiapnt, usually with its own code executed either before or after. Think of how Windows chains WindProc where you can perform code before or after the prio WindProc, and can eve choose not to call it.

These filter objects could be decorators if implement the same interface as the core object and then they wrap each other. But your code sample had the objects in a simple list. In a decorator you'd often see this:

FilterA fA = new FilterA(coreObject);
FilterB fB = new FilterB(fA);
FilterC fC = new FilterC(fB);

Of course, this doesn't have to be done via constructor so, like I said, we'd need to see more code to know if that was a Decorator.

I'm inclined to think you were going after a "Pipes and Filters" pattern where the output of each operation is the input of the next, but even that is not clear without knowing more. I cannot tell if each filter acts upon the same thing (such as a giant String) or each is supposed to intercat with some facet of a Report object model.

For example, if a Report has an object property that is the current Encoder, then perhaps your Encode("utf8") filter merely acts as a fcatory that configures/installs an Encoder subclass to deal with the disk persistance strategy. Meanwhile your SubstituteText($predefined_substitutions_array) acts upon a Parameters collection owned by the report to swap in runtime values.

I'd suggest describing what you want to achieve and not so much how to achieve it.

Upvotes: 1

havexz
havexz

Reputation: 9590

I think you dont necessarily have to pick one pattern as in most real world problems one pattern generally does not cover the entire implementation. So in your spec you can specify all the patterns your implementation is inspired from. And you can document what is different in your implementation from original patterns.

In your specific case, it looks similar to Chain of Responsibility

You can also look for Decorator pattern as thats also meant to implement filter like features.

BTW another pattern similar to your is Command Pattern. So in your case generate of Report is like execute of Command and filters are commands in the List.

Upvotes: 2

Bozho
Bozho

Reputation: 597016

Looks pretty much like Chain of responsibility. Note that each filter can decide not to proceed on the chain. And there is usually a "chain" object that is passed to each subsequent filter.

If you don't need these chain semantics, it can be viewed simply as proxies around the target object.

Upvotes: 1

Andy White
Andy White

Reputation: 88345

The GoF "Chain of Responsibility" pattern came to mind. Here is a description from Wikipedia: http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

Upvotes: 2

Related Questions