zoukankan      html  css  js  c++  java
  • DDD

    一  DDD是一种业务分析方法

    这里首推ENode作者汤雪华的博客。

    DDD领域驱动设计是计算机软件行业为了项目能尽量趋向成功,根据多年经验总结出来的一套业务分析的方法论。其核心是消化特定业务领域的知识并创建忠实反映它的软件模型。

     
    • 添加到短语集
       
      • 没有此单词集:中文(简体) → ...
         
      • 创建新的单词集...
    • 拷贝

    DDD的分析部分  顶层设计

     统一语言:
    上下文 绑定上下文(Bounded Context 边界上下文  简称BC)

    电子商务就是 问题空间    管理后台可能对应一个sln  就是一个解决方案空间

     核心思想 分而治之

    分析部分最擅长处理两种场景

    一种是  业务复杂

    另一种 是 业务逻辑还没完全清除  比如初创企业

    一个解决方案中容纳多个BC  可以用命名空间的方式来体现BC的隔离

    分析BC内的业务  就需要聚合和实体的概念

    实体  领域中具有唯一标识的对象   ABP中有实体的泛型基类Entity    其中主要就是一个属性ID 其他的FullAuditedEntity或者CreationAuditedEntity 都是框架提供方便审计的基类扩展

    从命名空间上看 我们给BC一个名字 让他逻辑统领一份部分代码   这些代码主要就是实体类 

    实体类也有主次    典型例子就是ORder实体和OrderItem   虽然OrderItem有ID也是实体 但是单条OrderItem几乎没有业务意义   所以对OrderItem的操作通过对Order 代理 这里的Order就是聚合根

    把一组实体放在一起就是聚合   最有代表的实体就是聚合根  聚合之间 只能通过聚合根进行引用 不能直接引用聚合中的 非聚合根实体

    按order来说 其他聚合要引用order 的时候 记录的是OrderId 或者订单号  假设其他聚合要处理Order的OrderItem  野只能引用Order  让Order去处理OrderItem  这就是内聚的思想 或者叫封装

    或者叫关注点隔离 

    一开是看到Abp的  AggregateRoot和IAggregeateRoot的时候 都是蒙的 项目模板也没有这个基类的范例  再看看 这个基类提供的属性 DomainEvents 以及abp框架中涉及该属性机制的源码

    (看AbpDbcontext的savechange方法实现) 这时候 我们看到了事件怎么用 开始思考领域事件这个词  开始去学习DDD

    当我们开始思考事件的时候  我们很自然的就回去思考实体的行为

    我们通过实体方法实现实体自己能够处理的业务逻辑  以 Tell not ask 的原则实现实体的行为 在行为成功完成后 抛出事件  以便外部协同  而聚合根(继承AggregateRoot基类或者实现IAggregateRoot接口)作为其他实体的代理 实现本聚合内的逻辑 通过 DomanEvents收集各类事件 交由Abp框架底层来触发事件 实现跨聚合甚至跨BC的协同(同时事件的发布订阅模式也是一种逻辑代码的

    解耦。顺序无关  EventHandler也可以回滚工作单元)

    另外 DDD的仓储模式是基于聚合根实体的(聚合根同时代理了非聚合根实体的仓储职责,就是说OrderItem不应有自己的仓储接口和实现)这一点在ABp中没有严格限制 或许是abp作者不希望把框架的使用门槛定的太高

    实体(聚合根也是实体)  只能实现自己范围内的业务逻辑 那范围外呢   (个人思考 是不是实体的业务逻辑相当于dal  领域服务相当于bll

    所有无法放到单个实体内的业务逻辑 都可以放到领域服务中去实现

    这包含 需要同一个实体类的多个实例配合的 需要不同实体类的多个实例去配合的 还有其他  只要是一个实体的实例无法完成自己的逻辑 就需要构建领域服务

    最后 最小的DDD构建  值对象  ABP框架中有一个基类 Value Object  即用来表示 值对象

    其实 DDD中的值对象对应到代码 有一个很宽泛的范围 可以认为

    所有没有唯一标识数据的数据对象  都是值对象

    最基本的 比如C#语言的值类型  像string int decimal 都是值对象 那么我们为什么还需要一个基类来辅助构造值对象

    第一个原因是 值类型 业务表达能力弱

    通过float 我们可以知道数量 但是不知道是重量还是体积

    通过decimal 我们能标识金额 但是不知道是人民币还是美元 

    所以我们需要自己构建值对象 来更准确的表达业务概念

    第二个原因是 方便

    值对象只能通过各个属性的具体值来比较来唯一确定  这个基类帮我们重写了equals()和GetHashCode() 并重载了相等和不相等操作符

    电脑实这里有个坑

    值对象 必须保证其不变性

    具体看abp谢列  为什么值对象必须设计成不可变的   而abp框架是无法控制你如何使用Valueobject的子类的 具体的说

    你的值对象必须关闭所有属性的setter  必须通过构造函数来初始化 且不允许通过方法去改变值属性

    上面讲的基本都是领域层 

    DDD将领域模型支撑架构的时候 特别提到了 封层 也是我们从abp中学到的分层方式 表现层  应用服务层  领域层  基础设施层

    表现层并不特指前端界面  mvc框架也只是一种表现层框架 他只是特别擅长处理http协议 

    应用服务层就是application程序集 是ddd建议的体现用例的一层  直接对接表现层(类似mvc控制器的协调作用 接受请求 返回dto) 用来编排任务 将工作指派给下层 所以应用服务的代码根据用例进行组织即可   (用例

    领域层即是业务模型的完整实现   (如果是完整实现 为什么还需要应用服务层

    基础设施层侧重于持久化技术  比如ef  但是不限于持久化技术  (通用功能接口的具体技术实现 类似仓储 , 接口定义在领域层 实现放在基础设施层) abp按照orm框架名称作为基础设施层的程序集命名可以理解  但是不能被其限制  个人建议另开一个程序集比如  Personball.Demo.Infrastructure 依赖与Personball.Demo.EntiyFramework 再让启动模块依赖infrastruture模块

    扩展 CQRS和事件溯源

    当我们说起经点领域模型的的时候  指的就是基于对象模型来实现业务  数据存储走关系型数据库 一切看起来很完美

    但是DDD研究的是复杂性

    软件开发行业几十年的经验积累下  前辈们发现如果把软件功能分成两个方面  假设系统中查询部门的复杂度是N 命令(创建或者变更数据)部分的复杂度也是N

    那么经点领域模型的情况下  系统的命令和查询混在一起  这个总体复杂度就是N乘以N  如果分开 那么美系统总体复杂度就会降低到N+N

    另一种说法是 对象模型的局限性日益显现  现在发现关注事件比关注对象更方便业务建模  因为现实世界是基于事件的 这引导我们可以用函数式编程来实现支撑架构 同时也引出了事件溯源架构

    CQRS  命令与查询职责分离 正如其字面上的意思  一个相当简单的原则 却非常有效的降低了系统的复杂性

    这里ing不是要推荐一个CQRS开发框架  只是提一下  大家可以在任何开发框架 任何场景下 按CQRS的方式去思考 都可以获得实际的好处

    再理一遍 

    统一语言 

    问题空间  子领域

    解决方案空间  绑定上下文 /上下文呢映射。  聚合/聚合根  实体  值对象

     原文地址 : http://www.360doc.com/content/18/1209/07/46368139_800353846.shtml

  • 相关阅读:
    不安装oracle客户端也可以使用pl/sql developer
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    c语言第一次作业1
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02,
    ASP.NET url重写与图片防盗链 I
  • 原文地址:https://www.cnblogs.com/liagon/p/14511351.html
Copyright © 2011-2022 走看看