Game Development Reference
In-Depth Information
Easily Adding New Functionality with the Visitor Pattern
One of the main goals of writing reusable game engine code is to try to avoid including
game-specific functionality in your classes. This can be hard to achieve with a pure object-oriented
approach, as the aim of encapsulation is to hide the data in your classes behind interfaces. This
could mean that you are required to add methods to classes to work on data that are very specific to
a certain class.
We can get around this problem by loosening our encapsulation on classes that must interact with
game code, but we do so in a very structured manner. You can achieve this by using the visitor
pattern. A visitor is an object that knows how to carry out a specific task on a type of object. These
are incredibly useful when you need to carry out similar tasks on many objects that might inherit
from the same base class but have different parameters or types. Listing 23-15 shows an interface
class you can use to implement
Visitor
objects.
Listing 23-15. The
Visitor
Class
class Visitor
{
private:
friend class Visitable;
virtual void OnVisit(Visitable& visitable) = 0;
};
The
Visitor
class provides a pure virtual method
OnVisit
, which is passed an object that inherits
from a class named
Visitable
. Listing 23-16 lists the
Visitable
class.
Listing 23-16. The
Visitable
Class
class Visitable
{
public:
virtual ~Visitable() {}
void Visit(Visitor& visitor)
{
visitor.OnVisit(*this);
}
};
The
Visitable
class provides a
Visit
method that is passed the
Visitor
object. The
Visit
method
calls the
OnVisit
method on the
Visitor
. This allows us to make the
OnVisit
method private, which
ensures that only
Visitable
objects can be visited and that we are always passing a valid reference
to the
OnVisit
method.
The visitor pattern is very simple to set up. You can see a concrete example of how to use the
pattern in Listing 23-17, where the Option class from Text Adventure has been inherited from
Visitable
.