DDD的精髓(1)

简介: DDD的精髓(1)

你可以,不代表你应该。

(Just because you can, doesn’t mean you should.)

——施莉琳•凯尼恩


在第6章中,我们简要介绍了什么是模型、模型在软件开发中的重要性,以及一些常用的建模方式在软件工程中的应用。本章将重点讲解领域驱动设计(Domain Driven Design,DDD),包括DDD的重要概念,以及如何进行领域建模。


7.1 什么是DDD


DDD是Eric Evans在2003年出版的《领域驱动设计:软件核心复杂性应对之道》(Domain-Driven Design: Tackling Complexity in the Heart of Software)一书中提出的具有划时代意义的重要概念,是指通过统一语言、业务抽象、领域划分和领域建模等一系列手段来控制软件复杂度的方法论。


DDD的革命性在于领域驱动设计是面向对象分析的方法论,它可以利用面向对象的特性(封装、多态)有效地化解复杂性,而传统J2EE或Spring+Hibernate等事务性编程模型只关心数据。这些数据对象除了简单的setter/getter方法外,不包含任何业务逻辑,业务逻辑都是以过程式的代码写在Service中。这种方式极易上手,但随着业务的发展,系统也很容易变得混乱复杂。


7.2 初步体验DDD


在介绍DDD之前,我喜欢用这个银行转账的案例来做一个DDD和事务脚本(Transaction Script)的简单对比。我们要实现一个银行转账的功能,如果用传统的事务脚本方式实现,业务逻辑通常会被写在MoneyTransferService中,而Account仅仅是getters和setters的数据结构,也就是所谓的“贫血模式”。其代码如下所示:


public class MoneyTransferServiceTransactionScriptImpl
      implements MoneyTransferService {
  private AccountDao accountDao;
  private BankingTransactionRepository bankingTransactionRepository;
  . . .
  @Override
  public BankingTransaction transfer(
      String fromAccountId, String toAccountId, double amount) {
    Account fromAccount = accountDao.findById(fromAccountId);
    Account toAccount = accountDao.findById(toAccountId);
    . . .
    double newBalance = fromAccount.getBalance() - amount;
    switch (fromAccount.getOverdraftPolicy()) {
    case NEVER:
      if (newBalance < 0) {
        throw new DebitException("Insufficient funds");
      }
      break;
    case ALLOWED:
      if (newBalance < -limit) {
        throw new DebitException(
            "Overdraft limit (of " + limit +") exceeded: " + newBalance);
      }
      break;
    }
    fromAccount.setBalance(newBalance);
    toAccount.setBalance(toAccount.getBalance() + amount);
    BankingTransaction moneyTransferTransaction =
        new MoneyTranferTransaction(fromAccountId,toAccountId,amount);
    bankingTransactionRepository.addTransaction(moneyTransferTransaction);
    return moneyTransferTransaction;
  }}


上述代码有些读者可能会比较眼熟,因为大部分系统都是这么写的。评审完需求,工程师画几张UML图完成设计,就开始像上面这样写业务代码了,这样写基本不用太动脑筋,完全是过程式的代码风格。


同样的业务逻辑,接下来看使用领域建模是怎么做的。在使用DDD之后,Account实体除账号属性之外,还包含了行为和业务逻辑,比如debit()和credit()方法。


public class Account {
  private String id;
  private double balance;
  private OverdraftPolicy overdraftPolicy;
  . . .
  public double balance() { return balance; }
  public void debit(double amount) {
    this.overdraftPolicy.preDebit(this, amount);
    this.balance = this.balance - amount;
    this.overdraftPolicy.postDebit(this, amount);
  }
  public void credit(double amount) {
    this.balance = this.balance + amount;
  }}


透支策略OverdraftPolicy也不仅仅是一个Enum了,而是被抽象成包含业务规则并采用策略模式的对象。


public interface OverdraftPolicy {
  void preDebit(Account account, double amount);
  void postDebit(Account account, double amount);}public class NoOverdraftAllowed implements OverdraftPolicy {
  public void preDebit(Account account, double amount) {
    double newBalance = account.balance() - amount;
    if (newBalance < 0) {
      throw new DebitException("Insufficient funds");
    }
  }
  public void postDebit(Account account, double amount) {
  }}public class LimitedOverdraft implements OverdraftPolicy {
  private double limit;
  . . .
  public void preDebit(Account account, double amount) {
    double newBalance = account.balance() - amount;
    if (newBalance < -limit) {
      throw new DebitException(
          "Overdraft limit (of " + limit + ") exceeded: "+newBalance);
    }
  }
  public void postDebit(Account account, double amount) {
  }}
相关文章
|
2月前
|
存储 JSON 自然语言处理
用 Java 接入大模型(二):流式还是非流式,到底怎么选
本文深入剖析流式与非流式API的核心差异,从响应结构、字段解析、错误处理、超时机制四大维度揭示选型陷阱;明确“用户是否等待”为关键判断标准,并提供可直接落地的7条决策清单,助你避免过早复杂化或体验降级。
213 1
|
10月前
|
人工智能 运维 前端开发
2026组织架构演进:职能与项目双视角管理的工具化实践指南
双视角管理融合职能专业化与项目价值交付,通过矩阵式架构实现技术深度与业务敏捷的平衡。依托板栗看板、Jira等工具,构建多维视图、智能优先级与自动化流程,提升研发效能与协作透明度。配套度量体系与渐进实施策略,助力组织在复杂环境中持续创新与高效交付。
|
6月前
|
存储 人工智能 弹性计算
阿里云“云工开物”第24期高校激励计划:学生认证立享300元无门槛券,邀请好友赢惊喜好礼!
阿里云“云工开物”第24期高校激励计划开启!认证学生即领300元无门槛券(有效期1年),覆盖ECS、AI、存储等多类云产品;邀好友还可赢惊喜礼品。5月31日前参与,速领福利!
|
5月前
|
人工智能 API 开发者
阿里云OPC创新助力计划:申请加入即刻解锁最低1000元 、最高100万元Token补贴
阿里云OPC创新助力计划采用"先用后返"模式,面向已实名认证的个人及企业用户,提供最低1000元、最高100万元的Token阶梯补贴,覆盖文本、语音、编码等核心模型,视频模型暂不参与。活动时间为2026年5月20日至9月30日,按月达标返券,需通过指定入口报名。此外,2026年6月还推出小额普惠权益,满20返20、满100返100、满200返200,新老用户均可参与。双轨并行大幅降低AI开发与应用试错成本,建议有AI落地需求的用户尽早报名锁定补贴。
|
6月前
|
人工智能 安全 数据可视化
企业级多 Agent 规模化落地怎么做?群虾智能 AI 沙龙 PPT 限时领取
关注微信公众号【阿里云云原生】,后台回复:0428,免费获得北京站讲师 PPT 合辑。
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
2025中国AI数字人技术类厂商评析与重点企业选择指南
数字人企业正乘科技浪潮崛起,资本与政策双轮驱动下迎来黄金发展期。像衍科技、阿里、百度等领军者依托技术革新与场景落地,推动数字人在金融、教育、医疗等领域规模化应用,实现从“虚拟形象”到“智能服务”的跨越,开启虚实融合的产业新纪元。
|
网络协议 Java 程序员
如何发布自己的项目到Maven中央仓库?
如何发布自己的项目到Maven中央仓库?
3271 0
如何发布自己的项目到Maven中央仓库?
|
前端开发 Java 数据库
SpringBoot入门(3) - 对Hello world进行MVC分层
本文介绍了如何在Spring Boot项目中实现MVC分层架构,通过将代码划分为controller、service、dao和entity四个部分,实现高内聚低耦合的设计。示例项目包括用户增删查改功能,详细展示了各层的具体实现及运行测试。
543 11
|
移动开发 小程序 JavaScript
uni-app多端应用开发:常见跨端兼容问题及处理策略
uni-app多端应用开发:常见跨端兼容问题及处理策略
2001 0

热门文章

最新文章