当前位置:

首页 > 编程开发 > 如何利用 JDK 17 的密封类(Sealed Classes)构建领域驱动设计中的受限继承体系

如何利用 JDK 17 的密封类(Sealed Classes)构建领域驱动设计中的受限继承体系

如何利用 JDK 17 的密封类(Sealed Classes)构建领域驱动设计中的受限继承体系 说起 Ja va 17 的密封类,很多人的第一反应可能是“增强版的 final”。其实不然,它更像是一份在编译期就强制执行的继承契约。它的真正价值在于,能让你在领域模型中清晰地宣告:“只有这几种状态或类

如何利用 JDK 17 的密封类(Sealed Classes)构建领域驱动设计中的受限继承体系

如何利用 JDK 17 的密封类(Sealed Classes)构建领域驱动设计中的受限继承体系

说起 Ja va 17 的密封类,很多人的第一反应可能是“增强版的 final”。其实不然,它更像是一份在编译期就强制执行的继承契约。它的真正价值在于,能让你在领域模型中清晰地宣告:“只有这几种状态或类型是合法的”,从而彻底告别靠文档或口头约定来约束的松散时代。

密封类必须显式声明 permits,且子类必须标注继承策略

这里有个关键细节:在 Ja va 17 中,permits 子句是必须显式声明的(自动推导功能要等到 Ja va 21+)。这意味着,任何遗漏、拼写错误,或者子类不在同一模块或包内,都会直接导致编译失败。这可不是运行时才抛出的检查,而是硬性的语法门槛。

  • permits 后面列出的每一个子类,都必须在代码中真实存在,并且不能是内部类(静态嵌套类除外)。
  • 每个被许可的子类,都必须用 final、sealed 或 non-sealed 中的一个来明确修饰,三者缺一不可。
  • 如果子类本身也是 sealed,那么它也必须携带自己的 permits 列表,从而形成一条可延续、受控的继承链。

领域建模时,优先用 final 子类封住具体实现分支

在进行领域驱动设计时,像 PendingStatus(待处理状态)、ShippedStatus(已发货状态)这类具体的值对象或状态,通常就不应该再被继承——它们代表一个确定的、完整的业务语义,额外的扩展只会引入歧义和混乱。

  • 此时,使用 final 修饰是最安全、最直接的选择,可以有效防止下游使用者意外覆写核心的行为逻辑。
  • 通用的抽象方法(例如 canTransitionTo(Status next))应该在密封父类中定义,然后由各个 final 子类去实现自己特有的状态转换规则。
  • 切记,不要为了追求形式上的统一而把所有子类都设为 sealed。如果一个分支在业务上确实没有继续细分的必要,那么用 final 来表达“到此为止”的意图会更加清晰。

non-sealed 不是后门,而是有明确开放意图的设计信号

那么,non-sealed 是留给开发者的“后门”吗?恰恰相反,它是一个强烈的设计信号。举个例子,在订单领域,OrderStatus(订单状态)密封类可能允许 RefundedStatus(已退款状态)和 CancelledStatus(已取消状态)。但 RefundedStatus 本身可能需要支持不同的退款渠道,比如 AlipayRefund(支付宝退款)、WechatRefund(微信退款)。这时,将 RefundedStatus 标记为 non-sealed,就等于明确宣告:“这个特定的状态分支,允许在当前的业务上下文内进行有控制的扩展”。

  • non-sealed 子类依然受到密封父类的保护:外部包无法直接继承顶层的 OrderStatus,只能继承你特意放开的那个特定分支。
  • 它不会破坏整体的密封性,只是一种局部的、有意的解耦设计。编译器仍然能对其他 final 或 sealed 的分支进行穷尽性检查。
  • 当然,滥用 non-sealed(比如给所有子类都加上)会让密封机制形同虚设,失去其核心价值。

和模式匹配配合时,switch 才真正“安全”

密封类的威力,在与模式匹配结合的 switch 表达式/语句中才得以完全展现。因为编译器确切地知道所有可能的子类型,所以它能强制校验你的 switch 是否覆盖了 permits 列表中的全部情况。

  • 当你写下 switch (status) { case PendingStatus p -> ... } 这样的代码时,如果漏掉了任何一个被许可的子类,编译器会直接报错。
  • 你不再需要添加一个“包罗万象”的 default 分支(当然,如果主动添加了,就会失去编译器的穷尽性保障)。
  • 未来如果在 permits 列表中新增子类,所有相关的 switch 代码都必须同步更新,否则无法通过编译——这是一种由工具保障的强一致性,远比依赖人工代码审查来得可靠。

所以说,真正的挑战往往不在于语法本身,而在于如何做出精准的设计判断:哪些类应该被密封?哪些子类应该用 final 彻底封闭?哪些又确实需要 non-sealed 来提供有限的扩展性?这完全取决于你对领域边界和业务演化方向的理解深度。错误地将本该封闭的分支放开,或将需要灵活性的分支锁死,都会导致领域模型要么失控,要么僵化。这才是用好密封类的关键所在。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发
相关文章 更多
UOS显卡驱动更新后闪屏怎么解决
UOS显卡驱动更新后闪屏怎么解决

统信UOS显卡驱动更新后屏幕闪烁需五步修复:一、Win+−或Win+0重置缩放并关闭放大镜;二、添加i915.enable_psr=0内核参数禁用PSR;三、图形界面切换开源驱动或APT降级至nvidia-driver-470;四、关闭“窗口特效”总开关并执行gsettings禁用ukui-comp

Linux怎么查看逻辑驱动器修复成功记录
Linux怎么查看逻辑驱动器修复成功记录

Linux中并没有所谓的“逻辑驱动器修复成功记录”。e2fsck或xfs_repair执行完成后,需要以终端输出作为判断依据。比如,ext4文件系统修复完成后,可能会显示“FILE SYSTEM WAS MODIFIED”,或者错误数得到修正;而XFS文件系统修复成功的话,末行通常会输出“done”

Win11新装系统如何快速装好驱动和更新
Win11新装系统如何快速装好驱动和更新

新装上Win11系统后,若想以最快速度补齐驱动和更新,顺序可别搞错了。得先让Windows Update把第一轮系统补丁和通用驱动跑完,接着处理重启收尾工作,最后再进入设备管理器查看还有哪些硬件没被完全识别。这么做可比一上来就往系统里塞各种厂商全家桶要稳当得多。 第一轮先直接跑 Windows Up

AMD发布26.6.4显卡驱动,正式解决两项RX 7000独显相关问题
AMD发布26.6.4显卡驱动,正式解决两项RX 7000独显相关问题

AMD又悄咪咪更新驱动了——这次是26.6.4版本,已经拿到WHQL认证。别看版本号只是小幅跳升,但对RX 7000系列及更高显卡的用户来说,这次更新直接补了两个关键坑。 第一个是驱动安装时的间歇性抽风:在Windows 10系统上往RX 7000系列及以上显卡装驱动,偶尔会卡住或报错,这回终于正式

统信UOS怎么在安全模式下装显卡驱动
统信UOS怎么在安全模式下装显卡驱动

必须通过安全模式安装显卡驱动:先确认或切换至multi-user.target,再禁用nouveau、安装编译依赖、停止lightdm并杀掉Xorg进程,最后在TTY中执行带--no-opengl-files等参数的.run安装命令。在统信UOS系统中遇到图形界面崩溃、黑屏或登录循环,无法进入桌面环

UOS系统显卡驱动文件夹在哪里
UOS系统显卡驱动文件夹在哪里

UOS中显卡驱动文件夹位于/lib/modules/$(uname -r)/kernel/drivers/gpu/drm/,按厂商分目录存放i915、amdgpu、nouveau等.ko模块;闭源NVIDIA驱动默认不自带,手动安装后通常落于/lib/modules/$(uname -r)/kern

Debian虚拟机驱动安装技巧
Debian虚拟机驱动安装技巧

Debian 虚拟机驱动安装技巧一、通用准备与排错思路保持系统最新:执行 sudo apt update && sudo apt upgrade,很多虚拟化相关组件与内核模块修复都依赖最新版本。安装编译与头文件依赖:准备 build-essential、linux-headers-$(uname -

Win11由于键盘驱动冲突蓝屏怎么解决
Win11由于键盘驱动冲突蓝屏怎么解决

WDF_VIOLATION蓝屏由HP键盘驱动hpqkbfiltr.sys(v11.0.3.1)或MacBook的MacHALDriver.sys引发,需通过WinRE重命名对应.sys文件为.bak后缀以跳过加载。Win11刚开机就直接蓝屏了,错误代码清楚地显示为WDF_VIOLATION,连登录界

大型集团企业数据治理方案,以“应用驱动”的数据治理策略|行业方案
大型集团企业数据治理方案,以“应用驱动”的数据治理策略|行业方案

数据治理是推动大型集团企业转型升级、提升竞争优势、实现高质量发展的重要引擎。通过搭建大数据平台,实现对业务系统数据的采集、清理、建模、整合,建立一个符合业务需求的数据决策平台,形成企业数字化转型关键能力,支撑数据赋能业务价值,最终推动组织及管理升级,实现数字化转型。以某拥有多元主业的综合型产业集团为

Linux怎么查看显卡驱动的具体版本
Linux怎么查看显卡驱动的具体版本

要确认当前正在运行的NVIDIA驱动版本,唯一的命令就是cat /proc/driver/nvidia/version,因为它直接读取已加载内核模块的元信息。而nvidia-smi显示的是NVML库协商的接口版本,这个版本可能存在缓存、滞后或伪造的情况,所以无法准确反映真实的加载状态。cat /pr

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
Postman macOS版
Postman macOS版
Mac

Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。

Docker Desktop macOS版
Docker Desktop macOS版
Mac

Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。

Android Studio macOS版
Android Studio macOS版
Mac

Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。

WINDOWS 更多
PixPix 网页版
PixPix 网页版
Windows

PixPix 是面向品牌、卖家和内容团队的在线 AI 图片视频创作平台,提供图视频 Agent、无限画布、图片生成、视频生成、自然语言编辑及商品套图、产品精修和带货视频等电商工具。

Postman Windows版
Postman Windows版
Windows

Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等

Docker Desktop Windows版
Docker Desktop Windows版
Windows

Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。