13

I have learned both the patterns but did not understand the differences between these two patterns.

I do not know scenarios, when and where to use these patterns.

Can any one explain the differences and use cases?

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • 3
    This is a good way to relate to the different patterns: http://www.cours.polymtl.ca/inf3700/divers/nonSoftwareExample/patexamples.html – jco.owens Nov 28 '12 at 13:46
  • 3
    link is broken now.. can you update @jco.owens? – Joe Dec 31 '15 at 08:20

6 Answers6

25

The main difference is that the Strategy Pattern encapsulates a single group of related behaviors, while the Visitor Pattern encapsulates multiple such groups.

  • You should use the Strategy Pattern when you need to encapsulate a behavior - If you have a family of algorithms and you need to choose among them at run time, you should use Strategy Pattern. This is very common: it happens every time you program to an interface.
  • You should use the Visitor Pattern to implement double dispatch - If you have a group of algorithms that need to be virtual in relation to more than one object. This is far less common, in part because it is much harder to implement.
Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    +1, you could more details with examples but it's a good geeky concise answer. – Scorpion Nov 28 '12 at 13:47
  • @dasblinkenlight Can you elaborate what you meant by "If you have a group of algorithms that need to be virtual in relation to more than one object." – Geek Jan 30 '13 at 14:53
  • @Geek The classic example is expression trees. On one hand, you have a group of classes following the composite pattern (base expression, constant expression, binary expression, function call, etc.) On the other hand, you have a group of classes implementing algorithms (convert to XML, print to text file, evaluate, etc.) Thus the method that you want to call depends on the subtype of the expression **and** the subtype of the algorithm, so behavior is virtual with respect to more than one class. The official name for it is [*double dispatch*](http://en.wikipedia.org/wiki/Double_dispatch). – Sergey Kalinichenko Jan 30 '13 at 15:00
  • it's not harder to implement, *once you know how*. It's just classes, relating to each other in various ways. Once you write them once, there isn't much more to do, but to use them or add to them. – Dennis Nov 17 '15 at 22:01
  • I agree your thoughts but it's a little bit restricting IMO. Many of the developers also uses Visitor for separating concerns in a single class quite frequently. Thus, "double dispatch" is not only/essential criteria for applying a Visitor pattern. – stdout Nov 19 '16 at 12:11
5

Visitor pattern intent:

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Use Visitor pattern if:

  1. Similar operations have to be performed on objects of different types grouped in a structure
  2. You need to execute many distinct and unrelated operations. It separates Operation from objects Structure
  3. New operations have to be added without change in object structure
  4. Gather related operations into a single class rather than force you to change or derive classes
  5. Add functions to class libraries for which you either do not have the source or cannot change the source

Even though Visitor pattern provides flexibility to add new operation without changing the existing code in Object, this flexibility has come with a drawback.

If a new Visitable object has been added, it requires code changes in Visitor & ConcreteVisitor classes. There is a workaround to address this issue : Use reflection, which will have impact on performance.

Refer to oodesign article and sourcemaking articles for more details

Strategy pattern intent:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.

Strategy lets you change the guts of an object.

Refer to below SE questions for more details:

Real World Example of the Strategy Pattern

Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
3

Visitor pattern is used to traverse the object hierarchy and provide some functionality like printing or reporting etc., I used this to provide different formats (Text/HTML) to print an object hierarchy by writing multiple visitors, one for each format. The objects in the hierarchy are the visitables.

Strategy pattern is used to pick a particular logical path based on the input. A classic example is authentication filters where based on the value in the Authorization HTTP header, different authentication strategies like NTLM/Negotiate/Basic are picked and run. The filter would hold a reference to the AuthenticationStrategy interface, based on the incoming request, a particular authentication strategy is picked and assigned to this reference and the code that follows doesn't need to know the exact strategy being used.

Vikdor
  • 23,934
  • 10
  • 61
  • 84
  • 1
    a simple example of strategy pattern - use of different implementation of Comparator to sort a list differently? – Scorpion Nov 28 '12 at 13:53
3

Visitor is for when you have a family of classes and you need to add new functionality to every class in that family but not touch the classes themselves (or wish to have that new functionality all defined in one place - the visitor)

Strategy is for when you have a family of classes that need to be able to do something in order to work properly (such as sort some objects they contain) but you want the client or your dependancy injection to tell them which way to go about doing that.

andrew pate
  • 3,833
  • 36
  • 28
0

In addition to the behavioural difference mentioned above, I also experienced a difference regarding the dependencies and use cases during a project once I was working on, like the following.

For example, Visitor knows about concrete classes. So you will be more flexible at the expense of changing your visitor code as you add new concrete classes to the hierarchy. There's no such thing in Strategy. In this context, Strategy becomes more suitable if you've methods only to return some output with a given input, regardless of the context.

Moreover, Visitor pattern also used to implement SRP of SOLID, to separate concerns.

stdout
  • 2,471
  • 2
  • 31
  • 40
0

Imagine you are building a cash register app that's building receipts. And let's say you want to:
1. ensure that different kind of items (books, fruit, meat, toiletries etc) are being processed differently
2. keep the logic of actual calculation of the price separately from the item definitions
3. ensure that if the shop starts selling something completely new (let's say cloth that will be charged by length), you won't have to change too many codes

Visitor could be a class that defines different kinds of calculations depending on what kind of item is being processed. It's a service that moves away the differences in price calculations away from the hierarchy of items.
enter image description here

where the body of getPrice could look like this:

getPrice(Calculation c) {
    return c.calculate(this);  // <-- visitor.visit( specific implementation )
}

and in say ShoppingCart you will do:

calc = getPriceCalculator()
foreach item in items:
    totalPrice += item.getPrice(calc)

Imagine this scenario: On Black Friday you want to do some crazy discounts, 70% off of all books, 50% off of all fruit. You can easily do something along the lines:

BlackFridayCalculator extends PriceCalculator {
    calculate(Book b) { return 0.3 * parent.calculate(b) }
    calculate(Fruit f) { return 0.5 * parent.calculate(f) }
}

// and in getPriceCalculator:
return (black friday time) ? new BlackFridayCalculator() : new PriceCalculator();

Strategy instead could have a hierarchy of a different kind of calculations (strategies) and each item would then define, which calculation (strategy) should be used ("plugged").

enter image description here

Now there are many ways how to define which item should use which calculation. The most straightforward would be giving Item method getCalculator and let each item choose which calculation it needs.

This might be a bit less dynamic - in a sense that each item needs to have a predefined calculator that will be used. But think of this scenario: Owner of the shop decides that pineapples and watermelons should be sold per piece - we can easily let Fruit use WeightCalculator by default and create a subset of fruit that will be sold by quantity.

LihO
  • 41,190
  • 11
  • 99
  • 167