Replace conditional with polymorphism – nice in theory but not practical

conditionalpolymorphismrefactoring

"Replace conditional with polymorphism" is elegant only when type of object you're doing switch/if statement for is already selected for you. As an example, I have a web application which reads a query string parameter called "action". Action can have "view", "edit", "sort", and etc. values. So how do I implement this with polymorphism? Well, I can create an abstract class called BaseAction, and derive ViewAction, EditAction, and SortAction from it. But don't I need a conditional to decided which flavor of type BaseAction to instantiate? I don't see how you can entirely replace conditionals with polymorphism. If anything, the conditionals are just getting pushed up to the top of the chain.

EDIT:

public abstract class BaseAction
{
    public abstract void doSomething();
}

public class ViewAction : BaseAction
{
    public override void doSomething() { // perform a view action here... }
}

public class EditAction : BaseAction
{
    public override void doSomething() { // perform an edit action here... }
}

public class SortAction : BaseAction
{
    public override void doSomething() { // perform a sort action here... }
}


string action = "view";  // suppose user can pass either "view", "edit", or "sort" strings to you.
BaseAction theAction = null;

switch (action)
{
    case "view":
        theAction = new ViewAction();
        break;

    case "edit":
        theAction = new EditAction();
        break;

    case "sort":
        theAction = new SortAction();
        break;
}

theAction.doSomething();    // So I don't need conditionals here, but I still need it to decide which BaseAction type to instantiate first. There's no way to completely get rid of the conditionals.

Best Answer

You're right - "the conditionals are getting pushed up to the top of the chain" - but there's no "just" about it. It's very powerful. As @thkala says, you just make the choice once; from there on out, the object knows how to go about its business. The approach you describe - BaseAction, ViewAction, and the rest - is a good way to go about it. Try it out and see how much cleaner your code becomes.

When you've got one factory method that takes a string like "View" and returns an Action, and you call that, you have isolated your conditionality. That's great. And you can't properly appreciate the power 'til you've tried it - so give it a shot!

Related Topic