I recently saw an OO design question on some forum and started thinking of using RTTI. However this must be bad design but I am unable to think of an alternative. Here is the simple question :
Create a C++ program for the following scenario using OO concepts –
My dog, named Buddy, lives in the backyard. He barks at night when he sees a cat or a squirrel that has come to visit. If he sees a frog, and he is hungry, he eats it. If he sees a frog and he isn’t hungry, he plays with it. If he has eaten 2 frogs already, and is still hungry, he will let it go. If he sees a coyote, he crys for help. Sometime his friend Spot stops by, and they chase each other. If he sees any other animal, he simply watches it. I would expect that you would have an animal class, and a cat, dog, squirrel, coyote class that inherits from the animal class.
I started thinking of having a see() method in the dog class which takes an Animal argument and then checks the actual type of the object (frog, cat etc) and takes the required action – play, chase etc depending on the actual type. However this would require RTTI which must be bad design. Can anybody please suggest a better design which would avoid RTTI and also point out the mistake in my thinking?
There are a ridiculously large number of ways to satisfy this problem using “OO concepts,” depending on what you want to emphasize.
Here’s the simplest solution that I can come up with:
If you need multiple kinds of “perceiving” animals, it’s straightforward to make a virtual wrapper for
see(producing a form of double dispatch):The above requires that the
Animalclass know something about theBuddyclass. If you don’t like your methods being passive verbs and want to decoupleAnimalfromBuddy, you can use the visitor pattern:The second mechanism could be used for purposes other than Buddy seeing an animal (possibly for that animal seeing Buddy). It is, however, more complicated.
Note that OO is definitely not the only way to solve this problem. Other solutions exist that may be more practical for this problem, such as storing the properties of the various animals that cause Buddy to bark, eat, play, etc. This additionally decouples the
Buddyclass from theAnimalclass (even the visitor pattern needs an exhaustive list of everything that Buddy can perceive).