Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD: subclasses & root entities

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!

like image 456
Bruno Reis Avatar asked Aug 26 '09 22:08

Bruno Reis


People also ask

What is a subclass in D&D lore?

You can help the D&D Lore Wiki by expanding it. A subclass is a variation of a character class . Community content is available under CC-BY-SA unless otherwise noted.

What is the difference between classes and subclasses in Dungeons & Dragons?

If classes are the meat of Dungeons & Dragons, subclasses are the seasonings that make the dish unique and interesting. Of course, there are the subclasses that are popular and powerful, but what about the ones that require a little more thought? What about the ones that have higher potential in role-playing as opposed to damage?

Are there any 5th edition classes in D&D?

The following list of Dungeons & Dragons 5th edition character classes includes every character class and subclass which appeared in an official Dungeons & Dragons 5th edition product. It does not include classes and subclasses appearing in Unearthed Arcana or third-party works.

What are subclasses and how do they work?

Every class has subclasses which add more specialization and flavour to the character. These subclasses level up when your class levels up (not your total character level). Certain classes unlock their subclasses at higher levels, while others might unlock at the lower levels.


3 Answers

You shouldn't use inheritance to model your domain because you will soon run into trouble once model starts to get complex.

President is simply a role of the person and person can have multiple roles. Maybe president got just one role but that's simply accidental by choosing wrong example.

Ferrari shouldn't be inherited from car either. It's not obvious on Ferrari example, because they only do one type of cars but consider company making many types like vans, sedans, hatchbacks, trucks and so on. You will probably want to make classes for every type that will inherit from car class. And then what... are you going to make five Toyota classes that will inherit from each type? Such as...

Car -> Sedan -> ToyotaSedan
Car -> Truck -> ToyotaTruck
Car -> Hatchback -> ToyotaHatchback

That would be ridiculous.

Disclaimer: I know nothing about about cars. However...

Don't use inheritance to model your domain. Ever.

Try it without inheritance and it will also became obvious how to persist your domain.

like image 69
lubos hasko Avatar answered Sep 22 '22 07:09

lubos hasko


Generally when you cross root aggregate boundaries you only allow the reference to be of the ID of the other root aggregate. You then use that ID to look up the other aggregate in its repository.

So in your case you would want President to have a Car ID and if you ever needed to do something to the President's car you would use the Car ID to go to the repository to get the car. President would not have a reference to the Car itself.

Now about that Ferrari. It's kind of difficult to enforce that in standard DDD terminology. Normally you would put some validation on the assignment of a Car to a President. Or perhaps there is a CarBuyingService just for Presidents that makes sure you get it right. Normally in DDD specializations are not themselves root aggregates.

like image 30
Mike Two Avatar answered Sep 23 '22 07:09

Mike Two


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.

like image 35
Joseph Ferris Avatar answered Sep 20 '22 07:09

Joseph Ferris