🐘

【DDD】エンティティ

2 min read

エンティティとは

エンティティとは一意なものを表現する概念です。例えば社員番号などで社員を一意に識別することで、同じ人物であることを把握し、年齢や所属といった属性を変更できます。

書籍「ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本」[1]では、値オブジェクトの特徴について、このように書かれています。

  1. 可変である
  2. 同じ属性であっても区別される
  3. 同一性により区別される

次のサンプルコードを見て、特徴と照らし合わせながら確認していきます。

class Employee {
  private readonly employeeId: string
  private name: string
  private age: number

  constructor(employeeId: string, name: string, age: number) {
    if (!employeeId) throw new Error("employeeIdが見つかりません")
    if (!name) throw new Error("nameが見つかりません")
    if (!age) throw new Error("ageが見つかりません")

    this.employeeId = employeeId
    this.name = name
    this.age = age
  }

  get EmployeeId() {
    return this.employeeId
  }
  get Name() {
    return this.name
  }
  get Age() {
    return this.age
  }

  equals(arg: Employee) {
    return this.employeeId === arg.employeeId
  }

  changeName(name: string) {
    if (!name) throw new Error("nameが見つかりません")
    this.name = name
  }
}

const employee = new Employee("1", "yamada", 20)
employee.changeName("tanaka")
console.log(employee.EmployeeId, employee.Name, employee.Age) // "1",  "tanaka", 20

1. 可変である

エンティティは振る舞いにより、属性を変更することが出来ます。changeNameメソッドにより、直接名前を変更しています。

changeName(name: string) {
  if (!name) throw new Error("nameが見つかりません")
    this.name = name
}

2. 同じ属性であっても区別される

属性が同一であっても同じ物として扱うことができません。サンプルコードでは、名前や年齢が同じ、つまり新たにもう1人tanakaさんがいても、同じ名前だけで同一人物として扱えません。

では何で判断しているかというと、idのような識別子で判断します。以下のequalsメソッドにより同じ属性値でも、識別子によりtanakaさんを区別することが出来ます。

equals(arg: Employee) {
  return this.employeeId === arg.employeeId
}

3. 同一性により区別される

エンティティは属性が異なっても識別子は変わらないため、同一と見なす必要があります。サンプルコードでは苗字がyamadaさんからtanakaさんに変わりました。苗字という属性が変わっただけで全く別の人物にはならないため、同一とみなすことが出来ます。

const employee = new Employee("1", "yamada", 20)
employee.changeName("tanaka")
console.log(employee.EmployeeId, employee.Name, employee.Age) // "1",  "tanaka", 20

以上がドメイン駆動設計入門で言われている3つの特徴です。

参考

https://nrslib.com/bottomup-ddd/#outline__3_2_1
https://pickles-ochazuke.hatenablog.com/entry/2021/01/05/025146

Discussion

ログインするとコメントできます