个人对DDD(领域驱动设计)理解,以及对实际开发的优化

目录DDD简单介绍个人理解DDD落地到具体开发的优化总结 DDD简单介绍 什么是DDD?让我们看看Wiki上怎么说领域驱动设计(英语:Domain-drive

DDD简单介绍

什么是DDD?让我们看看Wiki上怎么说

领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂需求的软件开发方法。领域驱动设计的前提是:

  • 把项目的主要重点放在核心领域(core domain)和域逻辑
  • 把复杂的设计放在有界域(bounded context)的模型上
  • 发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题

领域驱动设计是一种由域模型来驱动着系统设计的思想,不是通过存储数据词典(DB表字段、ES Mapper字段等等)来驱动系统设计。领域模型是对业务模型的抽象,DDD是把业务模型翻译成系统架构设计的一种方式。

个人理解

个人认为完全的遵循某一架构思想来实现一个大型项目是不可能的,正如你也不可能不使用任何架构思想来实现一个大型项目。实际上我们在开发中或多或少都可能已经使用到了DDD的设计思想,正如我们在学习的时候,老师在介绍MVC之前我们也许就已经会将代码结构按照一定的规则区分,等老师讲的时候才发现原来我们用的是MVC的设计思想。

DDD落地到具体开发的优化

根据定义不难发现DDD的核心是域模型。大白话就是相对于普通的模型,域模型还可以附带一些处理自身相关逻辑的方法,对比现实世界,一只鸟有属性(例如:体重,种类,翅膀宽度等等),但是鸟也有一些动作(例如:飞行,叫唤等等),因此这是很容易想象的。
那么在实际开发中,一个用户对象同样也存在属性(username,password,age...),但是也可以赋予它一些行为。下面举一个最常见的用户登陆的例子,大部分介绍DDD的也会举这个例子:

不使用域模型


  @Autowired
  private IUserService iUserService;
   
  // LoginInfo  是一个最普通的Java对象,包含表单上传的username和password的字段,以及一些getter和setter方法。
  @PostMapping("/login")
  public String login(LoginInfo loginInfo){
    // 相信大部分人都是这样处理的: 在 IUserService 中编写校验用户合法性的代码,然后返回校验结果最后返回一个Token给前端。实例代码简化处理。
    if (iUserService.checkUserEffect(loginInfo)){
      return "token";
    }
    return "fail";
  }

代码逻辑本身并无任何问题,也一目了然。但是随着项目的成长,登陆的同时可能需要做很多额外的操作,并且随着定义的Service的数量上升,往往也会出现不知道该去哪个Service找具体的方法的情况。那么看看域模型如何处理。

  // 于非域模型的最大区别是 LoginInfo 此时已经是一个模型,因此他除了包含属性之外还可以执行一些行为。
  @PostMapping("/login")
  public String login(LoginInfo loginInfo){
    if (loginInfo.doCheckEffect()){
      return "token";
    }
    return "fail";
  }

通过这样的方式,让系统更符合显示世界,也将方法正确的划分到类型。

总结

所有的开发思想只是思想而不是标准规范,应该尽量去思索其中适合自己,适合团队,适合公司,适合项目的部分。