parkr parkr - 2 months ago 24
Java Question

Avoiding parallel inheritance hierarchies

I have two parallel inheritance chains:

Vehicle <- Car
<- Truck <- etc.

VehicleXMLFormatter <- CarXMLFormatter
<- TruckXMLFormatter <- etc.


My experience has been that parallel inheritance hierarchies can become a maintenance headache as they grow.

How do I avoid a parallel inheritance hierarchy without breaking the concept of separation of concerns?

i.e. NOT adding toXML(), toSoap(), toYAML() methods to my principal classes.

Answer

I am thinking of using the Visitor pattern.

public class Car : Vehicle
{
   public void Accept( IVehicleFormatter v )
   {
       v.Visit (this);
   }
}

public class Truck : Vehicle
{
   public void Accept( IVehicleFormatter v )
   {
       v.Visit (this);
   }
}

public interface IVehicleFormatter
{
   public void Visit( Car c );
   public void Visit( Truck t );
}

public class VehicleXmlFormatter : IVehicleFormatter
{
}

public class VehicleSoapFormatter : IVehicleFormatter
{
}

With this, you avoid an extra inheritance tree, and keep the formatting logic separated from your Vehicle-classes. Offcourse, when you create a new vehicle, you'll have to add another method to the Formatter interface (and implement this new method in all the implementations of the formatter interface).
But, I think that this is better then creating a new Vehicle class, and for every IVehicleFormatter you have, create a new class that can handle this new kind of vehicle.