Visitor Design Pattern Examples

Learn about the visitor design pattern with some coding exampels.

C++ example

Let’s look at an example where we have a base class of File, which is implemented by three classes named ArchivedFile, SplitFile, and ExtractedFile. Let’s assume that we want to apply an operation Dispatch to all the files without affecting the object’s structure. Adding this method to the File class hierarchy doesn’t sound like a good idea because Dispatch doesn’t really belong in that object structure.

We’ll create a visitor class called AbstracttDispatcher and a concrete visitor class called Dispatcher. Depending on the object type, it will add an operation to the file objects. Let’s look at its code.

Press + to interact
#include <iostream>
#include <vector>
class AbstractDispatcher;
class File {
public:
virtual void Accept(AbstractDispatcher& dispatcher) = 0;
};
class ArchivedFile;
class SplitFile;
class ExtractedFile;
class AbstractDispatcher {
public:
virtual void Dispatch(ArchivedFile& file) = 0;
virtual void Dispatch(SplitFile& file) = 0;
virtual void Dispatch(ExtractedFile& file) = 0;
};
class ArchivedFile : public File {
public:
void Accept(AbstractDispatcher& dispatcher) override {
dispatcher.Dispatch(*this);
}
};
class SplitFile : public File {
public:
void Accept(AbstractDispatcher& dispatcher) override {
dispatcher.Dispatch(*this);
}
};
class ExtractedFile : public File {
public:
void Accept(AbstractDispatcher& dispatcher) override {
dispatcher.Dispatch(*this);
}
};
class Dispatcher : public AbstractDispatcher {
public:
void Dispatch(ArchivedFile&) override {
std::cout << "dispatching ArchivedFile" << '\n';
}
void Dispatch(SplitFile&) override {
std::cout << "dispatching SplitFile" << '\n';
}
void Dispatch(ExtractedFile&) override {
std::cout << "dispatching ExtractedFile" << '\n';
}
};
int main() {
ArchivedFile archived_file;
SplitFile split_file;
ExtractedFile extracted_file;
std::vector<File*> files = {
&archived_file,
&split_file,
&extracted_file,
};
Dispatcher dispatcher;
for (File* file : files) {
file->Accept(dispatcher);
}
}

Coding explanation

  • Line 4: We declared an AbstractDispatcher class.
  • Lines 6–10: We created a
...