Re: When and where to use Visitor Pattern?



"topmind" wrote:
> Could you perhaps provide more detail on the Midi example with
> Visitor? I have played around with Midi hobby projects, and thus can
> relate to it somewhat.

I have a class hierarchy of MIDI message classes (e.g. ChannelMessage,
MetaMessage, SysExMessage, etc.). Each class implements an IMidiMessage
interface. The IMidiMessage interface has an Accept method that takes a
MidiMessageVisitor object. The MidiMessageVisitor class is an abstract
class with virtual methods for visiting each of the message types. An
implementing visitor class can be derived from the MidiMessageVisitor
class and only overload the methods of the messages it's interested in.

To give a concrete example of how this structure is used, take a Track
object. It is a collection of MIDI message objects (IMidiMessage
references). When the track is played back, the messages are retrieved
one at a time. This is driven by a tick generator. When a tick event
occurs, the next event in the track is checked to see if it is time to
retrieve it.

This is where the Visitor pattern comes into play. What you do with each
message is dependent on the type of the message. If it is a channel
message, you would send it to the MIDI device. If it is a meta message,
you would do something different. For example, if the message is a meta
tempo change message, you would change the tempo of the tick generator.
So as the track is iterated over, the Accept method of each message is
called and passed the visitor object responsible for responding to MIDI
messages. The message object in turn calls the appropriate method of the
visitor object passing itself as a parameter. This approach enables you
to traverse a Track without having to do explicit type checking on the
major types of MIDI messages.

There are dozens of different types of MIDI messages, and it was
tempting to make each type into a class, but I decided not to. I kept
the hierarchy shallow with enough specificity to make it useful. For
example, there is a MetaMessage class that serves as a general class for
meta messages. It has a Type property representing the specific type of
meta message. In practice, this approach has worked out well for me. For
more information, you can check out my article on Code Project:

http://www.codeproject.com/cs/media/MIDIToolkit.asp






.