What is the difference between Strategy pattern and Visitor Pattern?

dotnetstep picture dotnetstep · Dec 29, 2011 · Viewed 17.1k times · Source

I have trouble understanding these two design patterns.

Can you please give me contextual information or an example so I can get a clear idea and be able to map the difference between the two of them.

Thanks.

enter image description here

enter image description here

Answer

ahoffer picture ahoffer · Jan 4, 2012

The strategy pattern is like a 1:many relationship. When there is one type of object and I want to apply multiple operations to it, I use the strategy pattern. For example, if I have a Video class that encapsulates a video clip, I might want to compress it in different ways. So I create a bunch of strategy classes:

MpegCompression
AviCompression
QuickTimeCompression

and so on.

I think of the visitor pattern as a many:many relationship. Let's say my application grows to to include not just video, but audio clips as well. If I stick with the strategy pattern, I have to duplicate my compression classes-- one for video and one for audio:

MpegVideoCompression
MpegAudioCompression

and so on...

If I switch to the visitor pattern, I do not have to duplicate the strategy classes. I achieve my goal by adding methods:

MpegCompressionVisitor::compressVideo(Video object)    
MpegCompressionVisitor::compressAudio(Audio object)

[UPDATE: with Java] I used the visitor pattern in a Java app. It came out a little different than described above. Here is a Java version for this example.

// Visitor interface
interface Compressor {

  // Visitor methods
  void compress(Video object);
  void compress (Audio object)
}

// Visitor implementation
class MpegCompressor implements Compressor {

  public void compress(Video object) {
    System.out.println("Mpeg video compression");
  }

  public void compress(Audio object) {
    ...
  }
}

And now the interface and class to be visited:

interface Compressible {

  void accept(Compressor compressor);
}

class Video implements Compressible {

  // If the Compressor is an instance of MpegCompressionVisitor,
  // the system prints "Mpeg video compression"
  void accept(Compressor compressor) {
    compressor.compress(this);
}