Let’s say I have the typical entity Car
class Car : Entity
{
public double MaxSpeed { get; set; }
public Color Color { get; set; }
/* ... */
}
This entity, in my domain model, would be the root entity of an Aggregate.
Now let’s say I specialize cars. I create a Ferrari, and the happy owners of Ferraris like to call them by a nickname:
class Ferrari : Car
{
public string Nickname { get; set; }
}
Let’s say I have another entity, the Company entity. It would be the root entity of another Aggregate. There are many people working on a company, represented by the entity Person. Persons may have cars. But the President of a company is usually very rich and this kind of people, they have Ferraris:
class President : Person
{
public Ferrari Ferrari { get; set; }
}
In this situation, I have the entity President, who is inside the Company Aggregate, that is holding a reference to a Ferrari, an specialization of the root entity of another aggregate.
Is this correct in view of DDD? Can/should I consider the specialization of root entities themselves as root entities of the same aggregate? I mean, in the domain I described, is the entity Ferrari also the root entity of the Car Aggregate (since Ferrari is also a Car)?
Now let’s say I have to persist this model to a Database. I think that my question does not depend on the OR/M framework I will use.
How should I build the table holding Cars? Should I build a single table Cars, with a “CarType” column (possible values: “Car”, “Ferrari”), and a nullable Nickname column?
Or should I build a table for Cars and a table for Ferraris, the latter one having its PK a FK of Cars?
Thanks!
I think you start losing a lot of the flexibility of the system by creating concrete types of these entities. The type of relationship that you are implying is something I generally hand with a “Type” entity. For example, you have a car. A Ferrari is a type of car. The two entities that are borne from that are a Car and a CarType.
The way that you are talking about doing it, you would have to add new entities every time a new type is introduced. If all that you are trying to capture is the “nickname” of the car, I would think that is just another piece of data, and not another entity. Unless you have different data (i.e. different property names) and/or behavior differences in Car entities for different types, you do not gain much with this approach. I would rather have repository methods like FindCarByType() and deal with one type of entity, to reduce risk.
I am by no means a DDD expert, and I am struggling with some concepts (or more like struggling with the multiple interpretations of some concepts). I am finding that there is not a 100% pure implementation, and that there are nuances to each implementation that I have seen.
Edit Follows
I see that I misread part of what you had written. I see that nickname is not for all vehicles, but just for Ferrari : Car. I think that the answer is really “it depends”. How much domain specialization do you have in the rest of your model? Having a nickname might be prevalent amongst Ferrari entities, but is it exclusive? It isn’t only about the actual data, but the requirements. Basically it comes down to how much specialization your are expecting in these entities.