I wrote a post some time ago called Inheritance with symfony and Doctrine ORM. In it I explored the different types of inheritance Doctrine ORM offers. I have a strong opinion on which is best; others strongly disagreed with what I said and it was clear the topic needed further exploration.
But maybe we’re barking up the wrong tree with the whole inheritance thing.
Since relational databases are relational and object-oriented programs are object-oriented, it seems that there’s a necessary awkwardness when trying to get the two paradigms to talk to each other in the same terms. As far as I know, no good solution exists.
I’ve come up with a solution to this problem by redefining the problem. Instead of asking, “How can I get a relational database to map nicely to inheriting classes?” I’ve said, “Let’s take away the inheritance. What happens when we get a relational database to make to a composite instead of an object hierarchy?” In my opinion, so far, it seems to work out pretty well. At least, better than inheritance. (By the way, I’m sure I’m not the first person to think about this problem this way.)
Let’s look at an example. Let’s say we have three types of vehicle: a bicycle, a golf cart and a car. I would design this with four tables:
vehicle make model color bicycle vehicle_id style golf_cart vehicle_id number_of_seats car vehicle_id body_type transmission_type
Here’s how you might create a new
Car (in Ruby):
car = Car.new # Vehicle attributes car.vehicle.make = "Geo" car.vehicle.model = "Metro" car.vehicle.color = "red" # Car attributes car.body_type = "coupe" car.transmission_type = "manual" car.save
The advantage I see to this is that you don’t have to have object-relational mapping handling inheritance. I admit that it’s a little awkward to have to say
car.vehicle.model instead of just
car.model. However, I don’t know of any ORM design that’s free of awkwardness and to me this is less awkward than trying to tell your ORM which tables inherit from which and all that stuff.
Maybe this is a great idea. Maybe it’s not a very good idea at all. I’m not sure yet. I do know that I used inheritance in a good-sized app and it’s caused me headaches, and I used composition in a different good-sized app and it’s working out great. I’ll probably use composition for everything in any future projects. I’d love to know what you think of it.