当前位置: 首页 > news >正文

领域驱动设计DDD 规约详解 - 指南

一、什么是规约(Specification)?

规约(Specification)是领域驱动设计中的一种重要模式,属于战术设计层。它用来表达对象应该满足的业务规则或条件(即“什么是合格的”)。规约可以复用、组合,使复杂的业务规则易于表达、维护与测试。

简单来说:规约负责以可表达、可重用的对象形式表示企业的业务规则和标准。


二、规约的典型应用场景

  1. 复杂的筛选条件
    比如“所有状态为启用且余额大于1000的用户”。
  2. 业务验证
    比如“只能对未发货订单进行取消”。
  3. 组合业务规则
    e.g. 某操作必须满足多个条件,可以用规约组合这些条件。

三、DDD中规约的结构

通常,Specification模式包括:

  • 接口/抽象类:定义isSatisfiedBy方法,判断某对象是否满足规约。
  • 具体实现:针对某些具体业务条件实现isSatisfiedBy
  • 规约组合:可以通过AndOrNot等方式组合规约。

典型接口定义如下(伪代码,更偏Java/C#风格):

public interface Specification {boolean isSatisfiedBy(T candidate);Specification and(Specification other);Specification or(Specification other);Specification not();
}

四、规约实现举例

以“用户”聚合为例,用Java仿写演示:

public interface Specification {boolean isSatisfiedBy(T candidate);default Specification and(Specification other) {return candidate -> this.isSatisfiedBy(candidate) && other.isSatisfiedBy(candidate);}default Specification or(Specification other) {return candidate -> this.isSatisfiedBy(candidate) || other.isSatisfiedBy(candidate);}default Specification not() {return candidate -> !this.isSatisfiedBy(candidate);}
}
public class EnabledUserSpecification implements Specification {@Overridepublic boolean isSatisfiedBy(User user) {return user.isEnabled();}
}
public class RichUserSpecification implements Specification {@Overridepublic boolean isSatisfiedBy(User user) {return user.getBalance() > 1000;}
}
// 组合使用
Specification enabledAndRich = new EnabledUserSpecification().and(new RichUserSpecification());
User u = ...;
if(enabledAndRich.isSatisfiedBy(u)){// 满足规约
}

五、规约在实际开发中的作用

  1. 屏蔽复杂条件逻辑
    通过组合、复用规约,解决if嵌套的“地狱”。
  2. 业务语言表达能力增强
    代码贴近业务,业务人员更容易理解。
  3. 便于测试和演化
    每个规约单一职责、易于测试,支持业务规则的灵活变更。
  4. 与持久化、查询解耦
    规约可用于内存判断,也可转换为数据库查询(比如JPA的Spec)。

六、一些实用建议

  • 没有复杂规则,不必引入规约,保持简洁。
  • 可将规约作为领域服务的一部分,实现时关注业务含义;
  • 对于需要持久化的规约(如数据库查询),可用如JPA Specification等工具。

七、参考资料

  • 《领域驱动设计:软件核心复杂性应对之道》(Eric Evans)
  • 《实现领域驱动设计》(Vaughn Vernon)
  • Specification Pattern (Martin Fowler)

八、规约与领域模型、领域服务的关系

在DDD中,业务规则可能分散在实体值对象聚合根领域服务中。规约的职责与它们有交集也有区别:

  • 实体自身的简单规则(如有某个属性、非空校验),可以直接放在实体方法里。
  • 涉及多个对象或者复杂业务规则,适合用规约表达。
  • 规约本身可以是领域服务的一部分(如某些跨聚合的校验)。
  • 聚合根保证一致性边界时,可以通过规约辅助判断修改是否合法。

九、业务用例示例(更贴近真实开发)

假设我们有一个电商系统,订单需要满足“可取消”这一业务逻辑:

1. 可取消规约(OrderCanBeCanceledSpecification)

领域专家对规则的描述
  • 未支付的订单可随时取消
  • 已支付、未发货订单可取消
  • 一旦发货则不可取消
  • 已完成或已关闭订单不可取消
代码实现(以Java、C#为例)
public class OrderCanBeCanceledSpecification implements Specification {@Overridepublic boolean isSatisfiedBy(Order order) {if (order.getStatus() == OrderStatus.CLOSED || order.getStatus() == OrderStatus.COMPLETED) {return false;}if (order.getStatus() == OrderStatus.SHIPPED) {return false;}return true; // PENDING(未支付)或 PAID(已支付未发货)可以取消}
}
应用方式
Order order = ...;
Specification canCancel = new OrderCanBeCanceledSpecification();
if (canCancel.isSatisfiedBy(order)) {order.cancel();
} else {throw new BusinessException("订单不可取消!");
}

十、规约的组合与复用

假设你在系统中有越来越多的业务规则。引入规约后,你可以通过组合,实现“与”“或”“非”等复合逻辑。

组合示例
Specification paid = order -> order.isPaid();
Specification notShipped = order -> !order.isShipped();
Specification canRefund = paid.and(notShipped);
if (canRefund.isSatisfiedBy(order)) {order.refund();
}

这样,假如你的规则变了,“已支付且未完成的订单可退款”,只需组合不同的规约。


十一、规约的持久化扩展(数据库查询规约)

在领域层判断规约往往是针对内存对象,但有场景需要用规约构造数据库查询(如JPA Specification、EF Core Specification等)。

以JPA为例
public class EnabledUserSpecification implements Specification {public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {return cb.equal(root.get("enabled"), true);}
}

你可以将领域规约转化为数据库查询规约,实现业务规则与持久层规则的解耦与统一。


十二、其他语言示例(Python)

class Specification:def is_satisfied_by(self, candidate):raise NotImplementedErrordef __and__(self, other):return AndSpecification(self, other)
class AndSpecification(Specification):def __init__(self, spec1, spec2):self.spec1 = spec1self.spec2 = spec2def is_satisfied_by(self, candidate):return self.spec1.is_satisfied_by(candidate) and self.spec2.is_satisfied_by(candidate)
class EnabledUserSpecification(Specification):def is_satisfied_by(self, user):return user.enabled
class RichUserSpecification(Specification):def is_satisfied_by(self, user):return user.balance > 1000
# 使用
spec = EnabledUserSpecification() & RichUserSpecification()
if spec.is_satisfied_by(user):# 业务逻辑

十三、规约在验证、权限、限流等的应用延展

  • 验证:将校验逻辑(如邮箱唯一、手机号校验等)封装为规约,可以复用于多业务流程。
  • 权限/授权:可将访问权限判断封装为规约,易于组合各种授权策略。
  • 限流/风控:对于风控规则快速变化场景,使用规约可弹性组合和测试。

十四、实践建议

  1. 不要滥用规约:简单业务不要引入规约模式,否则反而增加复杂度。
  2. 业务语言主导规约命名:用领域词汇表达规约名,如OrderCanBeCanceledSpecification
  3. 配合单元测试保证规约正确性:规约的复用性高,单元测试非常重要。
  4. 多用组合方式表达变化:应优先通过组合表达业务变化,降低重写规约的成本。

总结

规约 是DDD重要的战术模式之一,能抽象、表达并组合领域对象的满足条件,为业务规则实现提供良好支持。实际应用中,要根据项目复杂度酌情采用,利用好规约的复用与组合价值。

http://www.jsqmd.com/news/440309/

相关文章:

  • 科研人必看:2026年最好用的AI论文写作工具与云端Agent大盘点 - 沁言学术
  • 2026年 玻璃仪器厂家推荐排行榜,蜀牛/天玻/华鸥/博美品牌及成套玻璃仪器,专业品质与创新设计实验室优选 - 品牌企业推荐师(官方)
  • 2026年 昆山乱账整理服务推荐榜:专业高效清账纠错,助力苏州地区企业财务合规与健康发展 - 品牌企业推荐师(官方)
  • 阿里云 99 元/年,部署一套开源 OA、HRM、CRM、ERP 一体化企业管理系统
  • Linux线程(1):线程概念/Linux当中的轻量级进程,进程地址空间(完)--页表
  • 北京小程序开发工作室怎么选?中等预算下的专业定制服务推荐 - 品牌2026
  • 沈阳开锁换锁便民服务引领者——沈阳老锁匠及行业同类小型机构推荐 - 海棠依旧大
  • 北京本地小程序开发团队如何选择?聚焦技术扎实与响应及时的专业力量 - 品牌2026
  • 2026年 机械手厂家推荐排行榜:工业机械手/注塑机机械手/桁架机械手/伺服机械手/上下料机械手,高精度自动化解决方案实力解析 - 品牌企业推荐师(官方)
  • 2026年北京小程序开发公司避坑指南:如何锁定高匹配度的定制化服务商 - 品牌2026
  • Python flask微信小程序的大学生党务党建知识在线学习系统_bk1o4225
  • Linux内核驱动——Ubuntu 网络启动环境设置与操作
  • 2026年靠谱的矿车工厂推荐:翻斗矿车生产厂家推荐几家 - 品牌宣传支持者
  • 常用的网站和工具
  • 2026年 双行星动力搅拌机厂家推荐排行榜,双行星搅拌机/实验室双行星搅拌机/双行星真空搅拌机/双行星混合搅拌机,高精度高效能搅拌设备深度解析 - 品牌企业推荐师(官方)
  • 2026年北京小程序开发公司甄选指南:定制化服务与行业解决方案深度解析 - 品牌2026
  • 【Azure Container App】Debug Console的调试工具试验(一)-- iputils / net-tools / procps
  • 北京小程序开发外包如何选择?注重交付质量与行业经验的服务商推荐 - 品牌2026
  • 2026年北京小程序开发公司深度解析:定制化服务如何赋能企业数字化转型 - 品牌2026
  • 2026年北京小程序开发公司优选指南:从需求匹配到落地交付的深度解析 - 品牌2026
  • 对外服 + 逻辑服:ionet 如何用分层架构解决 N*N 问题
  • 大模型产品经理需要哪些必备技能?如何成为大模型产品经理?(2026年最新)
  • java2
  • 2026年北京小程序开发公司怎么选?本地团队推荐这家全流程技术服务企业 - 品牌2026
  • Flutter 三方库 collection_ext 的鸿蒙化适配指南 - 极致函数式编程、集合操作手术刀、鸿蒙级数据处理效能专家
  • 2026适合送人的春节零食礼包:《旺旺大礼包》种类多性价比高的零食大礼包超值装 - Top品牌推荐官
  • 2026年 化学试剂厂家推荐排行榜:高纯/进口/无水/微生物检测等高端试剂源头实力解析 - 品牌企业推荐师(官方)
  • 小鹏第二代VLA本月开启推送,2026款小鹏X9纯电版同步首发
  • 逆向工程 之 随机颜色生成器代码解析与重构
  • Flutter 三方库 zard 的鸿蒙化适配指南 - 掌控文本预处理增强、高性能分词实战、鸿蒙级多维语义专家