Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm implementing what's basically an event log system for a larger system. I used Single-table inheritance to build out the table.

The problem I'm having is figuring out how to build out the classes from the database. It's easy enough for me to figure out what they are to load them into the database, but to pull them out and create objects and collections out of them is a little trickier. The only way I know of is to have a switch statement and hope that if someone implements a new object that they'll update the switch, but that doesn't seem practical.

I'm sure I'm getting something wrong about how I'm thinking of the factory pattern here.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

You might want to look at how Hibernate does it. See the SingleTableEntityPersister if you are truly using single-table inheritance.

Or better yet... just use Hibernate/NHibernate or another ORM and don't reinvent the wheel.

To be clear, I'm not a huge fan of ORMs, but phrases like "single-table inheritance" imply that you're already trying to object-relational mapping the "manual" way, and you'd save yourself a lot of time by using a tool that does all the heavy lifting for you.

If you must do it yourself for whatever reason... well, as you can see, there are different methods, but typically you will need to use a discriminator column, and for that you will either need a map, a switch statement, or a consistent convention (e.g. the discriminator value has an obvious relationship to the class name and you can instantiate it directly with reflection). Switch statement is going to be the fastest and is probably the preferred approach for a fairly small number of derived classes.

Tools like Hibernate can't do it that way because, obviously, it would require specialized knowledge about the specific hierarchy, which they don't have. You do have that knowledge, so you can skip all the mapping/reflection and just use switch/case in a factory class somewhere. The fact that someone might forget to update it in the future isn't really an argument... your factory should throw an exception as soon as it encounters an unknown discriminator value.

If you're really that worried, make the discriminator an enum, and write a unit test for the factory that iterates through every known enum value and tries to instantiate it with the factory. That way the future maintenance programmer will find out right away if they missed something.

share|improve this answer
    
The problem I have with tools that do it for you is when you get into inheritance I've usually had to do a lot of manual mapping myself (see asp.NET MVC). I haven't seen Hibernate, I'll take a look at that hough. –  Snowburnt Sep 29 '13 at 13:26
    
@Snowburnt: NHibernate and Fluent NHibernate have auto-mapping. But even if they didn't, is a few lines of mapping really worse than hundreds of lines of code? –  Aaronaught Sep 29 '13 at 16:08
    
It's a good point, one I'll have to think about. Generally I'd prefer something that makes the most sense semantically and for a clean database design, also reusability. if I can reuse those hundreds of lines of code then it's worth it. –  Snowburnt Sep 29 '13 at 19:08
    
@Snowburnt: Code usually has to be tested in several different applications before it can be considered "reusable". I don't see how it's worth it, considering that the reusable code has already been written - that's exactly what ORMs are for, and most of them don't place any special constraints on your database design, so it's as "clean" as you want it to be. –  Aaronaught Sep 29 '13 at 23:51
    
So why aren't you a fan of ORMs? –  Snowburnt Sep 30 '13 at 2:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.