30-28 之 DDD 战术篇1 - Entity 与 Value Object

在简单谈完战略篇後,接下来要进行战行篇,也就是将 DDD 实际的应用到程序码中。

在 DDD 战术层级有两个非常重要的概念 :

  • Entity
  • Value Object

接下来这篇文章要先来谈谈这东西。

什麽是 Entity ?

An Entity is an object defined not by its attributes, but a thread of continuity and identity, which spans the life of a system and can extend beyond it.

我自已简单的理解为 :

它是一个物件,有唯一标识 + 业务行为方法

  • 这些 Entity 都是充血模型,也就是它有属性与业务行为。而另一种贫血模型则只有迟性,它的业务行为都放在 service 层实现。
  • 一个 Entity 可能对应到多个资料库持久化物件 ( Persistent Object PO )
  • 多个 Entity 可能对应到一个 PO。例如有些情况下,为了性能,会将 customer 顾客 与 account 帐户资讯存在同一张表。

简单举个范例,假设我们有个钱包,而将它写成 Entity 如下,这就是一个实体 :

class Wallet{
    id: string
    value: number 
    addMoney(deposit : number): void{
        this.value += deposit
    }
    subtractMoney(debit: number): void{
        if(this.value < debit){
            this.value -= debit
        }
    }
}

那这个是从战略层级那来的 ? 是我们之前讨论的 Domain StoryTelling 下图的 Work Object 吗 ? 不 ~ 不是,比较准确的说,那个之後会谈的 Aggregate 比较像,而 entity 只是它里面的某个组成。

https://ithelp.ithome.com.tw/upload/images/20211012/20089358epeK24PpjM.png

DDD Entity VS Domain Model

什麽是 Value Object ?

与 Entity 的差别在於,没有唯一标识

举个例子,例如 Money,它事实上只需要有两个属性,一个代表币别,一个代表值,它不需要有个唯一标识说他是整个系统中唯一的。

class Money{
    value: number
    currency: string
}

通常会与 entity 这样一起用

class Wallet{
    id: string
    value: Money  <---------------------- 这里
    addMoney(deposit : number): void{
        this.value += deposit
    }
    subtractMoney(debit: number): void{
        if(this.value < debit){
            this.value -= debit
        }
    }
}

参考资料


<<:  Day 28 - 用 canvas 与 pdfjs 做文件签名(上)

>>:  Day 29 - WooCommerce: 接收虚拟帐号付款成功通知

30天打造品牌特色电商网站 Day.12 一定要有的导览列

导览列(Navigation)是每个网站必要且重要的元件,当使用者进到网页想马上找寻想要的资讯,好的...

Day-7 带着童年的好朋友任天堂红白机、重新在 HDMI 电视上发光吧!

写了好几天的事前准备、我想大家应该都腻了。终於、准备到了一定程度、可以进入本文了。这篇文章主要的目的...

DAY17: 实作提交表单的Post请求

学完Get请求後就不免要学一下Post请求了,在DAY15: HTTP GET请求的开头有提到,Ge...

Day 33 - 实作 S3 驱动 Lambda 函数进行镜像

Day 33 - 实作 S3 驱动 Lambda 函数进行镜像 AWS 有个教学课程,教学课程:使用...

Day 7. Hashicorp Nomad: Inspect a job

Hashicorp Nomad: Inspect a job 当一套工具有一个好的Web UI可以使...