状态模式中角色权限与状态流转整合方案咨询(DDD场景)
问题解答
1. 权限校验与状态模式的整合方案
完全可以将权限校验与状态流转逻辑整合,无需拆分到多个独立模式中。核心思路是扩展状态模式的判断上下文,把操作发起者的身份权限作为状态流转的必要判断条件,替代外部零散的条件判断。
具体实现方式:
- 让每个状态类(如
DraftState、ApprovedState、PublishedState)的流转方法(submit()、cancel()、delete()、edit()等)接收操作发起者的信息(比如封装好的User对象)作为参数。 - 在状态类内部同时完成状态合法性校验和权限校验:
- 比如
DraftState的submit()方法,先确认当前处于草稿状态,再校验操作人是否为课程创建者; PublishedState的edit()方法,直接校验操作人是否为管理员,同时确认课程已发布。
- 比如
如果后续权限规则变得复杂,也可以将权限判断逻辑抽离为领域内的策略类(如CoursePermissionStrategy),注入到状态类中,既保持状态类的单一职责,又实现逻辑的统一整合。
2. DDD架构下权限融入业务规则的合理性
将与业务实体强绑定的权限规则融入领域层,完全符合DDD规范,甚至是DDD倡导的核心实践。
原因如下:
- 这类权限本质是业务规则的一部分:比如“发布前仅创建者可取消课程”“发布后仅管理员可编辑”,这些规则是业务逻辑的核心组成,并非单纯的技术层面访问控制。
- DDD要求领域对象具备完整的行为能力,能自主判断操作的合法性。如果把这些权限校验放在应用层或外部,会导致领域对象退化为贫血模型,失去对自身业务规则的掌控。
需要注意区分两类权限:
- 领域级权限:与业务实体状态、行为强相关的规则,必须封装在领域对象(或状态类、领域服务)中;
- 系统级权限:如“仅管理员可登录后台”这类通用访问控制,适合放在应用层或基础设施层处理。
实践建议
- 封装操作发起者的身份信息为
User或Actor领域对象,作为参数传递给Course的操作方法(如course.submit(currentUser)); - 状态类内部通过
currentUser的属性或方法(如isCreator(course)、isAdmin())完成权限校验; - 若权限规则复杂,可抽离
CoursePermissionChecker领域服务,统一处理权限判断逻辑,避免状态类代码臃肿。
内容的提问来源于stack exchange,提问作者ThiloOS
相关产品推荐
相关产品推荐

