Domain-Driven Design - Entities in TypeScript
Before you look at the Entities example in TypeScript, you can see at my post on what Entities are in Domain-Driven Design.
Entity base class in TypeScript
abstract class Entity {
protected readonly _id: UniqueId;
protected constructor(id: UniqueId) {
if (!id)
throw new InvalidUniqueIdError();
this._id = id;
}
public equals(other?: Entity): boolean {
if (other === null || other === undefined) {
return false;
}
return this._id.equals(other._id);
}
}
About this code snippet:
- It is an
abstract
class: This prevents this class from being instantiated and allows to declare abstract methods. - It have a
protected readonly
id
property, so this property can only be populated within the constructor of the class that implements it. - The constructor validates if the
id
parameter is valid, and if not, it throws an exception, so no entities are created with an invalidid
property. - It have an
equals
method to verify equality with other entities by checking itsid
property.
Entity example in TypeScript
class Product extends Entity {
private _price: Price;
private constructor(id: UniqueId, price: Price) {
super(id);
if (!price)
throw new InvalidPriceError();
this._price = price;
}
static create(id: UniqueId, price: Price): Product {
return new Product(id, price);
}
public get id(): UniqueId {
return this._id;
}
public get price(): Price {
return this._price;
}
public updatePrice(price: Price): void {
if (!price) throw new InvalidPriceError();
this._price = price;
}
}
About this code snippet:
- It has private properties.
- Its properties are Value Objects.
- The constructor validates if the
price
parameter is valid, and if not, it throws an exception, so no entities are created with an invalidprice
property. - No public
constructor
: Other classes cannot create instances of this class, except for nested classes. - To create instances of this Value Object we do not call the constructor directly, but it uses the Static Factory Method pattern instead.
- It have
public getters
to read the current state of the entity. - It have public methods to change the value of the entity’s properties.