17

I'm raising this question because of another question I asked here on SO some days ago.
I had to solve an specific problem, and after two replies I got, I realized two patterns can help to solve that problem (and any other similar).

  1. Chain of Responsibility
  2. Strategy

My question is:

What exactly is the difference between those patterns?

Community
  • 1
  • 1
Oscar Mederos
  • 28,017
  • 21
  • 79
  • 123

6 Answers6

32

They're very different.

Strategy is about having a generic interface which you can use to provide different implementations of an algorithm, or several algorithms or pieces of logic which have some common dependencies.

For instance, your CollectionSorter could support a SortingStrategy (merge sort, quick sort, bubble sort). They all have the same interface and purpose, but can do different things.

In some cases you may decide to determine strategy inside. Maybe the sorter has some heuristics based on collection size etc. Most of the time it indeed is injected from outside. This is when the pattern really shines: It provides users the ability to override (or provide) behavior.

This pattern is base of the now-omnipresent Inversion of Control. Study that next once you're done with the classic patterns.

Chain of responsibility is about having a chain of objects which usually go from more detailed to more generic. Each of the pieces in chain can provide the answer, but they have different levels of detail.

Popular GOF example is a context help system. When you click on a component in your desktop app, which help to display? First item in chain could look for help for the very component you clicked. Next in chain could try and display help for the whole containing dialog. Next for the application module... and so on.

Looks like you haven't, but should, read the GOF "Design Patterns" classic.

Konrad Garus
  • 51,699
  • 42
  • 151
  • 223
  • thanks for your answer. Is it valid let `CollectionSorter` select which *strategy* use, or do it programatically somewhere else, depending on some criteria, instead being the user who does this? because all examples I see about *Strategy pattern*, the user always invokes the call using an specific strategy. – Oscar Mederos Feb 18 '11 at 08:43
  • @Oscar Mederos You could use chain of responsibility along with stragegy. You chain your set of strategies so that a given strategy should be able to process your desired behavior, based on "some common dependencies", as Konrad Garus pointed out. Spring framework, for instance, use this kind of scenario on Validator interface - See http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/validation/Validator.html -, which selects a strategy based on class which should be validated. – Arthur Ronald Apr 03 '15 at 06:48
10

In Chain of Responsibility, it is each object's responsibility to send the call on to the next object in the chain, if the object cannot handle it.

In Strategy, all objects have the same interface, but some outside force has to supply which one is used.

CodeBender
  • 33,435
  • 12
  • 116
  • 122
David Mårtensson
  • 7,430
  • 4
  • 31
  • 47
2

Most patterns look very similar in code (or even uml) but patterns are centrally about context, responsibilities the particular problem they intend to solve rather than a particular source code. both decouples different things and for different reasons.

The chain pattern separates the responsibility of sending a request from the handling of the request. there could be a number of classes that can handle the same type of request (these classes generally implement the same interface) but the pattern allows the request to be passed along from one class (in the chain) to the other until a handler who is most fit to handle the request gets it and is responsible for handling the request (or until a null handler gets it and indicates the end of the chain). If you allow the wrong handler to handle the request, the result may "NEVER" be correct

The strategy is about method of processing or algorithm selection. take example of a case where you want to calculate the average of some samples. Any algorithm may "ALWAYS" be correct in the given context (e.g all classes having a strategy does same thing: calculates the average ), but the way the average is calculated, or the strategy for calculating the average differs from one class to the other, and the strategy pattern allows you to select which strategy to use in a decoupled manner.

now compare this to the chain pattern , where there can be a request for calculating average in which there is one handler that is responsible for computing average and there could be another request to calculate the standard deviation in which there is another handler that is responsible for computing standard deviation. so the request to compute average will not in any situation be handled by any other handler other than the handler most fit. where as, any class in the strategy may calculate the average and if you don't like the way one class calculates average, you can "SWAP" one strategy for the other.

ways of implementing these in source code may differ from programmer to programmer but should PTSUT (pass the same unit test")

Edit:

It could happen that certain members of the chain of responsibility may use strategy pattern to do their work

Oscar Mederos
  • 28,017
  • 21
  • 79
  • 123
Samuel
  • 1,275
  • 16
  • 21
2

The most significant difference is a semantic behavior of the implementation.

A Chain of Responsibility can have 0...ALL of the responsibilities applied to an input and each Responsibility decides if acts on the input and then passes it on. This is a procedural pattern since all responsibilities may be applied.

Imagine applying a chain of filters to an input with each filter deciding if it should process the input or not before it passes it onto the next filter.

A Strategy has one and only one of the strategies apply to an input. This is a usually creational pattern since only a single strategy is applied.

Imagine deciding which database driver to use and how to create a connection out of a list of database drivers based on the input and once the correct one is found it is the only one that is used.

Both can be implemented as a List using a Visitor Pattern the difference would be you stop visiting when a Strategy returns true.

A Strategy Pattern can also be implemented as a Map where the Key is a Predicate that can decide to end the iteration of the keys and then you just get the Value and that is your result.

1

You can consider chain of responsibility as a special case of the strategy pattern, which is more generic. As stated by Konrad the problem you address with the pattern-based solution is different.

BTW: You can find a kind of strategy in almost any GOF pattern.

bertolami
  • 2,886
  • 2
  • 23
  • 41
0

Strategy pattern:

  1. It's a behavioural pattern
  2. It's based on delegation
  3. It changes guts of the object by modifying method behaviour
  4. It's used to switch between family of algorithms
  5. It changes the behaviour of the object at run time. One algorithm will be selected from a family of algorithm.

Have a look at this SE question for Strategy example :

Real World Example of the Strategy Pattern

Chain of Responsibility:

Chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.

Key points:

  1. Multiple objects may handle the request and handler may not be a specific object
  2. In Chain of responsibility pattern, the request will be passed through a chain of objects until it has been handled. But in Strategy, one specific algorithm will be selected at run-time from a family of algorithms.

Real world example : In a company, a designated role have particular limits to process purchase request. If person with a designated role does not have enough power to approve purchase bill, he will forward the command/request to his successor, who have more power. This chain will continue until the command is processed.

Refer to below useful SE questions/links

Chain-of-responsibility_pattern

Chain-of-responsibility-pattern from oodesign

chain_of_responsibility from sourcemaking

Community
  • 1
  • 1
Ravindra babu
  • 45,953
  • 8
  • 231
  • 206