+1  A: 

Just a few observations / questions...

  • if the different location formats have no overlapping fields, what is the commonality in them which would make them candidates for a subclass hierarchy? Can you actually define a common interface for the base class Location?
  • is a TypeALocation comparable with a TypeBLocation?
  • are the two locations in SpecialItem of the same type, or can they be mixed?
  • can an item change its location to a different type runtime?

As you state above, value objects can't be polymorphic. Based on what you describe, I don't see how can you treat locations polymorphically.

Update If you can't define a common base interface for your location types, it is very awkward to try and treat them polymorphically, regardless of whether there is ORM or not. Taking your example below, even for accessing any information about the actual location I live, you needed to downcast it to either a street address or a lat/long coordinate. Polimorphism is meant exactly to avoid the need for such downcasts (and switches on type fields, etc.)!

Looking at the options you describe above, with all this taken into account:

  1. Just as you, I don't like it either (hardly suprising).
  2. Can be a viable option if there aren't many location types and you can be reasonably sure that you have implemented all the types ever needed. In this case the domain class would practically be the analog of a C union, with a type field. It is a bit awkward to use, but the polymorphic attempt would be even more awkward IMHO.
  3. It is definitely an interesting idea which I will probably experiment with in a pet project sometime, but I am not quite sure I would like such tricks in my production code. I guess it could also be done with a custom mapping type which would map your component to a specific subclass. But then again, we're back trying to fit these incompatible types into a type hierarchy... the only good reason to try this path is if there are many location types and/or new types may appear in the future.
Péter Török
The commonality is that both Location types fulfill the same need. An Item must have a Location, but that requirement can be filled by either of the subtypes. (Note that the Location supertype is abstract.) The entities that own them would reference the supertype in order to accomodate either of the subtypes. For comparison, think of how you might specify where you live. You could specify either a street address or a latitude/logitude combination. Both formats accomplish the same thing, but there are no common fields. The 2 SpecialItem Locations could be of different types.
MylesRip
I don't believe there is a conceptual problem with treating value objects polymorphically. It just isn't currently supported by the ORM. An item's location could change *values*. In the domain model, this would be accomplished (assuming a value object approach) by replacing the reference with a new, immutable Location. Changing an Item's Location to a different *type* at runtime would not be supported in this application.
MylesRip
Granted there isn't much behavior in a Location. (I suspect most value objects don't have much behavior other than things like validation, display, sorting, etc.) I still need a way to handle the business requirement, which is that there are in fact multiple location formats, any of which are valid whenever a Location is required. Given the above situation, then, would you implement option 2? ...or something entirely different?
MylesRip
@MylesRip see the update in my answer.
Péter Török
Thanks for your input, Péter. I really appreciate the time you took to consider this situation! There aren't many Location types and I don't expect new ones to be added in the future (famous last words, I'm sure!) so it sounds like option 2 would be the best fit.
MylesRip