领域驱动设计(DDD)

领域驱动设计(DDD)文档

  • DDD 第 1 部分:战略领域驱动设计 https://vaadin.com/blog/ddd-part-1-strategic-domain-driven-design
    • 战略层要思考的是领域,子域,核心子域,通用子域,支撑子域,限界上下文,微服务划分,团队划分,工作分工等
  • DDD 第 2 部分:战术领域驱动设计 https://vaadin.com/blog/ddd-part-2-tactical-domain-driven-design
    • 战术上考虑建模:实体,值对象,聚合根,领域事件,领域服务,input/output port设计, 工厂模式使用,实体库(repository)持久化实体
  • DDD 第 3 部分:领域驱动设计和六边形架构 https://vaadin.com/blog/ddd-part-3-domain-driven-design-and-the-hexagonal-architecture
    • 六边形架构,代码目录,模块,限界上下文之间通过adapter交互,分布式事务等,消息队列等

领域驱动设计,六边形架构

adapter_input —> port/input(dto) --> application -->domain_service(domain_entity)---->port/output(dto) —> infra/output/adapter

  • adapter_input: 接收外部请求,实现如http, rpc接口,转为对内部的调用,如把http请求中的json格式转为dto对象,再调用input端口接口
  • port/input: 输入端口接口。只是一个接口规范,application里的服务实现此接口。 adapter_input里使用此接口。依赖倒置,使得adapter_input和application不依赖彼此,而是都依赖port/input接口
  • dto: 数据传输对对象。adapter_input和application不依赖彼此的数据格式,而是依赖中间的dto对象。做到数据模型隔离。 否则就得在port/input中使用Entity或者使用adapter中的格式。比如 http_adapter里收到的是json格式。我们也转为dto对像,再调用port/input接口, application实现了port/input对象,使用dto, 转为Entity对象使用
  • application:实现应用层逻辑,本身无状态,如参数校验,身份认证等等,数据库事务,事件监听器执行。而主要业务逻辑都在domain_service中。
  • domain_entity:如业务中需要保存跟踪状态的对象,一般有唯一ID标识。 当然有些复杂entity中包含其他entity,这种entity叫聚合根,它是entity,在用其他entity要用其他entity的id,而不是内嵌。 如果一个操作只涉及本entity内的状态变化,就把这个操作作为方法放到entity中。
  • domain_service:实现跨entity业务逻辑。不使用repository,由application使用repository获取实体。 实体+值对象—输入–>domain_service----输出—>实体+值对象。不一定非要domain_service,可能一个聚合根实体内部就能实现。
  • port/output(dto): domain_service/application里可能依赖外部服务,要先定义好接口,放在port/output下。由output/adapter去实现接口。同样dto是为了隔离
  • domain_service和output/adapter之间的数据模型依赖。 这里同样是依赖倒置。
  • output/adapter:外部依赖,小到一个log库,大到一个外部服务,如sso登录服务,都用适配器实现。方便日后更换。

聚合根

由实体和值对象组成。是一个事务一致所需要的所有且小状态。外部应用只与聚合根交互,不依赖、使用聚合内部的实体。
聚合之间是通过关联外部聚合根ID的方式引用。在一次事务中,最多只能更改一个聚合的状态,通过发事件改变其他聚合。
聚合中的实体中没有业务逻辑代码,只有对象的创建、对象的初始化、状态管理等个体相关的代码。
聚合根有修改本身状态的方法,但是方法的调用顺序由领域服务决定。聚合中不依赖output_port接口,不依赖repository,
领域服务使用repository来构建聚合需要的实体。

领域服务

封装行为
与状态无关的领域行为
聚合和端口之间的行为
变化方向与聚合不一致的领域行为
聚合之间协作的领域行为
能把行为封装在聚合中就不要使用领域服务,否则会让实体贫血

目录结构

顶层结构

.
|-- application
|-- domain
|-- input_adapter
|-- input_port
|-- main.py
|-- output_adapter
|-- output_port
`-- readme.md

port说明

port就是抽象接口:adapter和app都依赖接口。依赖倒置
port/input: application/domain实现它,input/adapter依赖它
port/output: application/domain依赖它,output/adapter实现它

dto说明

有时候发现dto和entity字段几乎一样,但最好还是新定义一个。 设想C++中可以用typedef等定义一下。

数据持久化与事务

在adapter中实现了输出端口中的repository接口。最好能收集一个事务中发生变化的实体。并在最后提交事务,完成原子操作。
同样收集事件,最后发布事件。 有时发布事件和实体保存要原子性,那只能把事件也作为实体保存到db中。再后台启动一个线程消费db中的事件,或者push到其它外部消息队列中。
比如每次可以new出EntityRepository和EventRepository,在此对象中反复get/update实体,或者发布事件。最后提交事务时把所有变化持久化。
建议使用乐观锁,可在实体中加个版本号,持久化时如果发现版本号变化(可能在并发操作同一实体),则不持久化,此时直接释放EntityRepository所有变化的对象即可

多用值对象

比如代码中经常用id, 地址, 用户名这些,图省事定义成了string, int. 不要这样用。尽量定义成一个类 struct UserName{ string user_name;}
值对象一般整体更新,不是修改其中的一部署成员。可以看成是常量

防腐层

dto, input/output port, input/output adapter形成了防腐层。使得domain中不依赖任何外部数据格式,接口等。

注意

实体,聚合根构成封装环境。内部不依赖port(如repository, 不感知外部数据库事务)领域服务可以依赖port,包括reposity.
需要的实体要在application服务中构建好,传进来。构建时用repository+工厂+builder模式。
聚合根是在数据层面的事务一致对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
领域驱动设计(Domain-Driven Design,简称DDD)是一种软件开发方法论,旨在解决复杂业务领域的软件开发问题。它强调将业务领域的知识和概念直接融入到软件设计和开发中,以实现更好的业务价值和可维护性。 在C#中实施DDD时,可以采用以下几个关键概念和技术: 1. 领域模型(Domain Model):领域模型是DDD的核心概念,它是对业务领域的抽象和建模。在C#中,可以使用类和对象来表示领域模型,通过定义实体(Entity)、值对象(Value Object)、聚合根(Aggregate Root)等概念来描述业务领域中的实体和关系。 2. 领域驱动设计的分层架构DDD通常采用分层架构来组织代码。常见的分层包括用户界面层(UI)、应用服务层(Application Service)、领域层(Domain Layer)、基础设施层(Infrastructure Layer)等。每一层都有不同的职责和关注点,通过良好的分层设计可以实现代码的可维护性和可测试性。 3. 聚合根和聚合聚合根是DDD中的一个重要概念,它是一组相关对象的根实体,通过聚合根可以保证一致性和边界。在C#中,可以使用类来表示聚合根,通过定义聚合根的行为和关联关系来实现业务逻辑。 4. 领域事件(Domain Event):领域事件是DDD中用于描述领域中发生的重要事情的概念。在C#中,可以使用事件(Event)或委托(Delegate)来表示领域事件,并通过事件驱动的方式来处理领域事件。 5. 仓储(Repository):仓储是用于持久化和检索领域对象的接口或类。在C#中,可以使用接口和实现类来定义仓储,并通过依赖注入等方式将仓储注入到其他类中。 6. 领域服务(Domain Service):领域服务是一种用于处理领域逻辑的服务。在C#中,可以使用类和方法来表示领域服务,并将其注入到其他类中使用。 以上是DDD领域驱动设计在C#中的一些关键概念和技术。通过合理运用这些概念和技术,可以更好地实现复杂业务领域的软件开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值