DDD领域驱动设计实战(三)-深入理解实体(下)

简介: DDD领域驱动设计实战(三)-深入理解实体(下)

5 创建实体

新建一个实体时,我们总期望通过构造器就能初始化足够多的实体状态,因为这样更容易通过各种条件查找到该实体。

在使用及早生成唯一标识的策略时,构造器至少需接受唯一标识参数。若还有可能通过其他方式查找实体,比如名字或描述信息,那应该将这些参数一并传给构造器。


有时一个实体维护一或多个不变条件(Invariant,在整个实体生命周期中都必须保持事务一致性的一种状态) 。


不变条件主要是聚合所关注的,但聚合根也是实体。


如果实体的不变条件要求该实体所包含的对象都不能为null或必须由其他状态计算所得,那么这些状态也需作为参数传递给构造器。

public class User extends Entity {
  ...
  // 每一个User对象都必须包含tenantld、username, password和person属性。
  // 即在User对象得到正确实例化后,这些属性不能为null
  // 由User对象的构造器和实例变量对应的setter方法保证这点
  protected User (Tenantld aTenantld
          String aUsername,
          String aPassword,
          Person aPerson) (
    this();
    this.setPassword(aPassword);
    this.setPerson(aPerson);
    this.setTenantld(aTenantld);
    this.setUsername(aUsername);
    this.initialize();
  }
  ...
  protected void setPassword(String aPassword) { 
    if (aPassword == null) {
      throw new 11legalArgumentException(
        "The password may not be set to null.");
    )
    this.password = aPassword;
  )
  protected void setPerson(Person aPerson) (
    if (aPerson == null) ( 
      throw new IllegalArgumentException("The person may not be set to null.");
    }
    this.person = aPerson;
  }
  protected void setTenantld(Tenantld aTenantld) ( 
    if (aTenantld == null) {
      throw new IllegalArgumentException("The tenantld may not be set to null."); 
    }
    this.tenantld = aTenantld;
  }
  protected void setUsername(String aUsername) (
    if (this.username != null) {
      throw new IIlegalStateException("The username may not be changed.n);
    }
    if (aUsername == null) {
      throw new IllegalArgumentException("The username may not be set to null."); 
    }
    this.username = aUsername;
  } 

User对象展示了一种自封装性。在构造器对实例变量赋值时,把操作委派给实例变量对应的setter方法,便保证了实例变量的自封装性。实例变量的自封装性使用setter方法来决定何时给实例变量赋值。


每个setter方法都“代表着实体”对所传进的参数做非null检查,这里的断言称为守卫(Guard)。setter方法的自封装性技术可能会变得非常复杂。所以对于复杂的创建实体场景,可使用工厂。


User对象的构造函数被声明为 protected。 Tenant实体即为User实体的工厂也是同一个模块中唯一能够访问User 构造器的类。这样一来,只有Tenant能够创建User实例。

public class Tenant extends Entity {
  // 该工厂简化对User的创建,同时保证了Tenantld在User和Person对象中的正确性
  // 该工厂能够反映通用语言。
  public User registerUser(String aUsername,
               String aPassword,
               Person aPerson) {
    aPerson.setTenantld(this.tenantld());
    User user = new User(this.tenantld(), aUsername, aPassword, aPerson);
    return user;
}

参考


https://tech.meituan.com/2017/12/22/ddd-in-practice.html

《实现领域驱动设计》

实体和值对象:从领域模型的基础单元看系统设计

https://blog.csdn.net/Taobaojishu/article/details/106152641


目录
相关文章
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7568 0
|
8月前
|
消息中间件 测试技术 领域建模
DDD - 一文读懂DDD领域驱动设计
DDD - 一文读懂DDD领域驱动设计
14091 3
|
消息中间件 开发者
DDD领域驱动设计实战(六)-领域服务(上)
DDD领域驱动设计实战(六)-领域服务
481 0
DDD领域驱动设计实战(六)-领域服务(上)
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
261 1
|
缓存 数据可视化 Java
浅析 DDD 领域驱动设计(2)
浅析 DDD 领域驱动设计
331 0
浅析 DDD 领域驱动设计(2)
|
设计模式 SQL 测试技术
一文理解 DDD 领域驱动设计!
以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然
一文理解 DDD 领域驱动设计!
|
数据挖掘 Java 测试技术
DDD领域驱动设计实战(三)-深入理解实体(中)
DDD领域驱动设计实战(三)-深入理解实体(中)
301 0
|
前端开发 Java 数据库连接
DDD领域驱动设计实战(03)-深入理解实体
DDD领域驱动设计实战(03)-深入理解实体
422 0
DDD领域驱动设计实战(03)-深入理解实体
|
安全 Java 项目管理
DDD领域驱动设计实战(六)-领域服务(下)
DDD领域驱动设计实战(六)-领域服务
583 0
DDD领域驱动设计实战(六)-领域服务(下)
|
安全 数据安全/隐私保护
DDD领域驱动设计实战(六)-领域服务(中)
DDD领域驱动设计实战(六)-领域服务
253 0
DDD领域驱动设计实战(六)-领域服务(中)

热门文章

最新文章