Domain Modeling for Humans and AI

Value Objects & Entities

Domain Modeling for Humans and AI

Lesson Description

The "Value Objects & Entities" Lesson is part of the full, Domain Modeling for Humans and AI course featured in this preview video. Here's what you'd learn in this lesson:

Mike explains value objects as data structures without unique IDs, such as RGB colors or distances, often embedded in other resources. In contrast, entities have unique IDs, are mutable, and are stored in databases to support relationships like one-to-one or has-many.

Preview
Close

Transcript from the "Value Objects & Entities" Lesson

[00:00:00]
>> Mike North: The first domain modeling concept we're going to dig into, the first pair of concepts are value objects and entities. What are value objects? These are things that you have to create some sort of data structure for. It could even just be like some special kind of string that has a convention to.

[00:00:20]
It doesn't have to be fancy, but these are things that don't possess a unique identity. What do I mean by this? Like, if you had something like an RGB color which already exists in this app, like, here's the path in the workshop project, which we'll check out in a moment.

[00:00:40]
You can see that I'm modeling an RGB color and I've got a red channel, a green channel, a blue channel, and an alpha channel for transparency. Now, we're not going to end up storing in database. In our little SQLite database that's holding all the seed packets and things behind the scenes, we're not going to be storing a table of colors where each color has an id and we're referring to colors by id.

[00:01:06]
I guess you could, if you were doing some sort of theming thing. But this you want to think about as being kind of embedded onto more interesting things. So we also have a concept of a distance that already exists the app. There's a value like three and then there's a unit like feet or centimeters or meters.

[00:01:26]
Those are value objects. And an important aspect of value objects is you should be able, through some code that you write, to be able to compare them against each other and check whether they're equal. Not by just checking ID equals id, but you're trying to figure out are these things equivalent.

[00:01:45]
So this gets a little bit interesting when you start thinking about units like is 3 meters equal to some precise number of feet? Maybe those are equal. That would be up to you to think about. Talk to your user. Does this make sense in that case? I'd argue probably.

[00:02:03]
So there are a couple things going on here in this code. First off, we're using a library called TypeORM. Don't worry if you've never used this, we're not going to have to worry about it too much and we'll incrementally get into this. But this is a tool for object relational mapping, and this just means we don't have to set up a database table and we don't have to write SQL queries.

[00:02:25]
There's nothing wrong with that if that's the way you like to engage with the database. But simply by creating a class like this and denoting that these Fields represent columns, where we're saying alpha is a column, and if it's not specified, let's assume it has a value of 1.

[00:02:45]
All the database stuff happens behind the scenes for us and we don't have to worry about it. The second thing is we've got this peashoot types package. We'll dive into this a little bit more, but I've factored out some shared types that our front end and backend both depend on, and in there you'll find common things that relate to the shared contract between these two system components.

[00:03:11]
So when our UI sends a request to our backend, there is a clear type for what that request shape and the response shape looks like, as well as any other objects that are embedded within that request and response. So that's what you can find in this types package.

[00:03:25]
In the types package, you'll see we're using a library called Zod. And again, if you haven't used this before, don't panic. We're going to get into it incrementally. But this is a way of defining schemas. So this adds on top of TypeScript, runtime type checking. So by defining an RGB color like this, we get something that we can use at runtime to validate that, yes, the red, green, and blue properties are on this object and they are in fact numbers.

[00:03:55]
You can see that we can mark something as optional or required. There's a lot here, and I want you to start with the assumption it's not strictly two, but start with the assumption that if you can articulate a type in TypeScript Zod, you can use to sort of articulate a schema and extract a type from that schema so that you can have both compile time type checking from TypeScript and runtime type checking from Zot.

[00:04:23]
Of course, this doesn't come for free. Unlike TypeScript types, this doesn't drop away as part of your compile process. But that's kind of the point. So that's value objects. They're sort of comparable things that typically get embedded into other resources, and they don't have an identity field like an id.

[00:04:44]
Now, let's talk about entities. So entities are mutable objects. Value objects are generally immutable. You create a new one. If you want to change the color of something, you create a new color that's a slightly different color. Entities are different. These represent things that you will persist. They are mutable, they can change.

[00:05:09]
And generally, at least in this app, they're all going to have an ID of some sort so if we're going to take a peek at what our database looks like, and you don't have to be a database expert here, but you're going to see that each of these corresponds to a table.

[00:05:23]
And the way you can tell the difference between a value object like this and an entity is this entity decorator that you're adding to the class. This is what signifies that this is sort of a top level thing that ends up being persisted in a database. When you start working with entities, relationships get really interesting.

[00:05:47]
You can have a has many relationship or a one to one relationship, whereas that color concept just ends up kind of being embedded in the object, if you will. We're going to walk through the process of checking the git repo for this gardening app out and we're going to kind of warm up and do some very basic modeling, like figure out what entities are important and value objects for a part of this app called the Temperature Date Calculator.

[00:06:16]
So the problem to solve here is as a gardener, I want to be able to select a location, type in a temperature, and I want to know what is the date where I can be assured that the temperature in my location will be at or above that level.

[00:06:39]
So a concrete example here is tomato plants. They want to go outside when the nighttime temperatures are above 50 degrees Fahrenheit. And so I need to know, what is that date? That's very important to me because I work backwards from that date to sort of like, how long do they have to grow inside and then when should I plant my seeds?

[00:07:01]
And sort of it's a really important part of sort of working back from the date they go outside.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now