One important point is decoupling. In your code above you need to know what cases exist. You have to list all of them every single time. If you put the logic from the switch branches into virtual methods, the calling code does no longer need
- what cases actually exist and
- what the logic for each case is.
Instead, the logic is placed where it belongs to - in the class.
Now think about adding another case. In your code, you would have to touch every single place in the program, where such a switch statement is used. Not only that you have to locate them (don't overlook any!), they might even be not in your own code, since you are writing code for some sort of libarry which other people use. With the virtual methods, you simply override a few methods as needed at the new class and everything will work immediately.
BaseTask = class
{
virtual void Perform() = 0;
}
TaskOne = class(BaseTask)
{
void Perform() { cout << "Formatting hard disk ..."; }
}
TaskTwo = class(BaseTask)
{
void Perform() { cout << "Replacing files with random content ..."; }
}
So now the calling code does only have to do
foreach( BaseTask task in Tasks) // pseudo code
{
task.Perform();
}
And now let's assume you add another task:
TaskThree = class(BaseTask)
{
void Perform() { cout << "Restoring everything form the backup..."; }
}
And you're done. No switch editing, no case adding. How cool is that?