Wednesday, October 24, 2007

Replace multidimensional if condition with double dispatch.

If you have a series of if conditions that vary in two dimensions it may be possible to replace the conditionals with double dispatch.


public class passenger
{
public Vehicle vehicle;
public string type;
public void travel()
{
if (vehicle.Type == "Car")
{
if (this.Type = "Rich")
{
RideInLimo();
}
else if (Passenger.Type = "Poor")
{
Drive();
}

else if (vehicle.Type = "Airplane")
{
if (this.Type = "Rich")
FlyInPrivateJet();
else if (Passenger.Type = "Poor")
{
FlyCoach();
}

}
}
}
}


In the above example the first refactoring that I would like to apply is Replace Type Code with Class. However the way a person travels does not only depend on the type of vehicle he uses but also the type of person they are as well. This problem can be solved by passenger passing itself as a parameter to the vehicle class. Then the vehicle class can use method overloading to create to versions of the travel method for each type of person.

Here is the refactored code.



public class Passenger
{
public Vehicle vehicle;
public void Travel()
{
vehicle.Travel(this);
}


}

public class Car : vehicle
{
public void Travel(RichPersion Passenger)
{
RideInLimo();
}
public void Travel(PoorPersion Passenger)
{
Drive();
}

}


public class Plane : vehicle
{
public void Travel(RichPerson Passenger)
{
FlyInPrivateJet();
}

public void Travel(PoorPerson Passenger)
{
FlyCoach();
}

}

One drawback of using this approach is that it violates the Open Close Principle because you will have to add a new version of the travel method on the vehicle object for each new person type that you add to your application.

No comments: