新来的架构师,把DDD落地得优雅又高级!

159 阅读4分钟

沉默是金,总会发光

大家好,我是沉默

在日常开发中,我们经常听到“DDD”这三个字母。

有人说它高级,有人说它难懂。
你可能也看过一堆长篇大论的 DDD 讲解,读完只觉得:“好像很厉害,但我真不会用。”

今天咱们用一个通俗易懂的案例告诉你:

DDD(领域驱动设计)到底是啥?它和传统开发有什么区别?怎么用到真实项目里?

DDD听上去高大上,其实落地也能很接地气。

**-**01-

DDD 是什么?

DDD,全称 Domain-Driven Design,领域驱动设计。

一句话总结:

用代码还原业务本质,而不是为了实现功能堆 if-else。

它的核心思想是:
把业务规则写到“懂业务”的对象里,让代码成为业务的镜子。

我们传统是:
PRD怎么写 → 程序员脑补 → controller/service/dao 东拼西凑。

而DDD更像是:
业务方讲清业务 → 画出领域模型 → 代码结构天然映射业务流程。

**-**02-

DDD和传统代码的差距

假设我们做一个用户注册功能,需求如下:

  • 用户名唯一

  • 密码必须符合复杂度要求

  • 注册成功后记录日志

传统开发这么写:

@Controller
public class UserController {
    public void register(String username, String password) {
        // 密码校验
        // 查询用户名是否存在
        // 保存数据库
        // 写日志
    }
}

业务、数据、流程,全都混在一起!

有人说:“我已经分层啦!”

public class UserService {
    public void register(User user) {
        ValidationUtil.checkPassword(user.getPassword());
        if (userRepository.exists(user)) { ... }
        userDao.save(user);
    }
}

嗯,分层是有了,但业务规则仍然乱飞:

  • 密码规则 → 工具类

  • 唯一校验 → service 层

  • 数据存储 → dao

DDD怎么重写注册功能?

我们来一把“代码内聚”操作,把业务规则放进 User 领域对象

public class User {
    public User(String username, String password) {
        if (!isValidPassword(password)) {
            throw new InvalidPasswordException();
        }
        this.username = username;
        this.password = encrypt(password);
    }
    private boolean isValidPassword(String password) {
        // 复杂度规则
    }
}

这里,User 不再只是数据容器(贫血模型),而是能“自己判断密码是否合规”的“业务对象(充血模型)”。

这样简单一改,谁再说“DDD只是分层”?

**-**03-

DDD三大关键设计

DDD不仅仅是让对象有行为,它还有三大核心概念:

聚合根(Aggregate Root)

聚合根是啥?一句话概括:

“你必须通过我来操作我手下的对象。”

比如一个用户(User)有多个收货地址(Address):

public class User {
    private List<Address> addresses;
    public void addAddress(Address address) {
        if (addresses.size() >= 5) {
            throw new AddressLimitExceededException();
        }
        addresses.add(address);
    }
}

用户自己控制地址添加,防止外部乱搞。

领域服务 vs 应用服务

  • 领域服务:负责跨实体的核心业务规则

  • 应用服务:负责流程编排,调用领域服务、消息通知等

public class TransferService {
    public void transfer(Account from, Account to, Money amount) {
        from.debit(amount);
        to.credit(amount);
    }
}
public class BankingAppService {
    public void executeTransfer(Long fromId, Long toId, BigDecimal amount) {
        Account from = repo.find(fromId);
        Account to = repo.find(toId);
        transferService.transfer(from, to, new Money(amount));
        mq.send(new TransferEvent(...));
    }
}

举个栗子:

领域服务 = 决策者

应用服务 = 指挥官

领域事件(Domain Event)

当一个重要业务动作发生时,比如“用户注册成功”,就可以发布领域事件:

public class User {
    public void register() {
        // 注册逻辑
        events.add(new UserRegisteredEvent(this.id));
    }
}

领域事件 = “系统内的广播”,用来驱动其他逻辑如发送短信、积分奖励等。

**-**04-

电商下单案例对比

传统开发:业务散、逻辑乱

public class OrderService {
    public Order createOrder(Long userId, List<ItemDTO> items, Long couponId) {
        // 校验库存
        // 计算价格
        // 应用优惠券
        // 保存订单
    }
}

业务规则到处是:

  • 库存逻辑 → Service

  • 优惠券逻辑 → Util

  • 总价计算 → Controller 或工具类

一改需求,Service 就成了“代码考古现场”。

DDD版本:业务逻辑高度内聚

public class Order {
    public Order(User user, List<OrderItem> items, Coupon coupon) {
        items.forEach(item -> item.checkStock());
        this.totalAmount = items.stream()
            .map(OrderItem::subtotal)
            .reduce(Money.ZERO, Money::add);
        if (coupon != null) {
            validateCoupon(coupon, user);
            this.totalAmount = coupon.applyDiscount(this.totalAmount);
        }
    }
    private void validateCoupon(Coupon coupon, User user) {
        if (!coupon.isValid() || !coupon.isApplicable(user)) {
            throw new InvalidCouponException();
        }
    }
}

改需求只需要调整 validateCoupon(),业务边界清晰明了。

**-**05-

什么时候该用DDD?

不要盲目上DDD,它不是银弹!

适合使用的场景:

  • 业务逻辑复杂(如电商、金融、供应链)

  • 需求频繁变更(如互联网产品、增长业务)

不推荐使用的场景:

  • 简单 CRUD(如数据管理后台、CMS)

  • 一次性项目(成本高,收益小)

一句话:

当你发现业务变更时,只改领域层就能搞定,那你真的把DDD用对了!

总结:

DDD的魅力在于:
让代码的结构贴近业务逻辑,让系统更容易理解、更容易维护。

  • 把规则写进对象,而不是 scattered everywhere

  • 把流程封装成服务,而不是 controller+util 拼图游戏

  • 把变化记录成事件,而不是“流程散记”

DDD不追求“写得快”,而追求“改得稳”。

如果有一天,你看代码就像看 PRD,那就是你 DDD 落地的时刻!

热门文章

一套能保命的高并发实战指南

架构师必备:用 AI 快速生成架构图

**-**06-

粉丝福利

点点关注,送你 Spring Cloud 微服务实战,如果你正在做项目,又或者刚准备做。可以仔细阅读一下,或许对你有所帮助!