DDD领域驱动设计

编程思想的升级

POP---面向过程编程

  首先说一个比较经典的场景,怎么把大象装进冰箱里面?第一步,打开冰箱门,第二步,把大象装进冰箱,第三步,关上冰箱门。到此结束。考虑问题的方式是123456。

  POP是一种线性思维,简单,无法应对复杂情况。比如,建房子的时候,我们只要考虑地基--墙--门窗--房顶。

OOP---面向对象编程

  面向对象编程特点,封装继承和多态。还是上面那个把大象装进冰箱的场景。我们需要考虑三个对象,人、冰箱、大象。人有把大象装进去的功能;大象有自己的属性;冰箱有打开冰箱、关闭冰箱的功能。。。。OOP是对象交互,完成功能,是可以累加的,可以构建大型系统。

  比如,在OOP思想下建造一个大厦,我们会分解成多个房子,然后每个房子是什么样子的,最后组成这个大厦。

  OOP中,是以类为基本单位的,类是静态的,在编译的时候是确定的,运行的时候是确定的,不方便扩展,不能扩展进去。比如,一个系统开发完成,领导让加一些功能,这个限制那个限制,总归是不方便去修改已经编译好的类,不然还要重新编译发布,再经过测试。有些人精通设计模式,通过设计模式也可以最小化的去修改类。但是设计模式,大多也是基于接口去设计的,但是设计模式也还是有限制的。还是在扩展方面有限制。

AOP---面向切面编程

  AOP,解决面向对象语言的静态问题,能突破类 限制,去动态扩展类的功能。任意扩展功能,聚焦业务逻辑,代码复用,集中管理,方便团队管理。

  AOP解决的事程序扩展问题,所以AOP㐊替代OOP,程序设计思想还是OOP,AOP红寺湖OOP的一个补充。

  怎么去实现AOP呢?dotnet mvc中,有哪些Filter,其实就是AOP,还有IOC中通过AutoFac对AOP进行的扩展。这些在我前面的随笔中都有介绍。

DDD---领域驱动设计(Domain--Driven--Design)

  上面说到了POP,是线性思维,是没有边界的,大盒子,全部东西都在里面。OOP,是面向对象的,是有边界的,以类为边界,有盒子的概念。

DDD领域驱动设计历史:

  早在2004年的时候,DDD这个概念就被提出来了,2015年的时候就销声匿迹了,因为太虚了,只有概念和理论,没有落地。2018年又开始火起来了,是因为微服务架构的出现。可能更多的人对于DDD并没有太多的概念,但是你在项目中见过这些东西吗?Repository、Entity、Service、DTO。这些都是依据DDD来设计出来的。

什么是DDD---领域驱动设计 

  软件开发不是一蹴而就的事情,我们不可能在不了解产品(或行业领域)的前提下进行软件开发,在开发前,通常需要进行大量的业务知识梳理,而后到达软件设计的层面,最后才是开发。而在业务知识梳理的过程中,我们必然会形成某个领域知识,根据领域知识来一步步驱动软件设计,这就是领域驱动设计的基本概念。

  DDD:它像是更小粒度的迭代设计,它的最小单元是领域模型,领域模型无关技术,具有高度的业务抽象性,它能够精确的描述领域中的知识体系;同时它也是独立的,我们还需要学会如何让它具有表达性,让模型彼此之间建立关系,形成完整的领域架构。

Domain--领域:

  领域:领域与具体开发技术无关。就是你的软件系统要解决的实际问题相关的所有东西的集合。

  子域:领域更细粒度的划分(核心子域、支撑子域、通用子域)。核心域是业务成功的主要促成因素,主要竞争力,支撑子域是支撑核心域的,而通用子域是业务系统的公用部分。用子域拆分组织架构。

  一个系统都是为了解决一个问题,问题里面包含多个问题域。比如,我们现在要做一个博客的系统,博客要怎么划分呢?可以划分为发帖、回帖、用户、积分这些领域,因为博客大家都熟悉,所以一下子就找出了领域。在拆分万作用于之后,会有一个统一的语言,需求、设计、开发、很对不熟悉的业务。

  实体:

    一个实体模型就是一个独立的事物。每个实体都拥有一个唯一的标识符,可以将它的个体性和所有其他类型相同或者不同的实体区分开。

  键值对:

    一个值对象,或者更简单地说,值,是对一个不变的概念整体所建立的模型。和实体不一样,它没有唯一标识符,而是由值类型封装的属性对比来决定相等性

  模块:

      在DDD中,模型中的模块表示了一个命名的容器,用于存放领域中内聚在一起的类。C#中模块称为命名空间。

  资源库:

    资源库通常表示一个安全的存储区域,并且对其中所存放的物品起保护作用。通常我们将聚合实例存放在资源库中,之后再通过资源库来获取相同的实例。

  防腐层:

    在集成两个设计良好的限界上下文时,在防腐层内部,它在你自己的模型和他方模型之间进行翻译转换。

  工厂:

    将创建复杂对象和聚合的职责分配给一个单独的对象,该对象本身并不承担领域模型中的职责,但是依然是领域设计的一部分。

Driven--驱动

  Driven,是一个动词,驱动、推动,

  1、基于领域驱动领域设计,目标为导向,为领域做设计。

  2、基于领域驱动代码实现,完成领域的需求,程序分析时,是不考虑实现的

Design--设计

  领域是核心,先确定共同领域,然后再进行代码设计和数据库的设计。

  在传统的开发中,比如,让你做个博客,那么我们就开始分析,数据+流程。设计数据库,这些东西怎么进行存储;再设计界面+数据访问。这种设计完之后,就容易需求变更,其实是需求分析不够,开发和需求的语言不同。

  界限上下文:每个限界上下文都有自己的代码库、数据存储以及开发团队,每个限界上下文选择的技术栈和语言平台也可以不同。 用限界上下文拆分系统。

  运用界限上下文与通用语言进行战略设计:

    1、DDD主要关注的是如何在明确的限界上下文中创建通用语言的模型;
    2、团队在限界上下文中发展了一种语言用于表达其边界内的软件模型,这一语言在该限界上下文中开发软件模型的每个团队成所使用。它之所以被称为通用语言,是因为团队成员间交流用的是它,软件模型实现的也就是它。

  运用子域进行战略设计:

    子域是整个业务领域的一部分,你可以认为子域代表的是一个单一的、有逻辑的领域模型。

    1、 DDD项目中总会碰到很多限界上下文,一定有一个将称为核心域,而其他的限界上下文之中也会存在许多不同的子域;

    2、团队最佳的建模成果:限界上下文与子域之间一一对应;

    3、敏捷项目管理核心即一个清晰的限界上下文,也是一个清晰的子域;

    4、在某些情况下,一个限界上下文中有可能存在多个子域,但这并非是最理想的建模结果。

  运用聚合进行战术设计:

    聚合是由一个或多个实体组成,其中一个实体被称为聚合根。聚合的组成还可能包括值对象。

    聚合的经验法则: 

      1、在聚合边界内保护业务规则不变形;
      2、聚合要设计得小巧;
      3、只能通过标识符引用其他聚合;
      4、使用最终一致性更新其他聚合。

为什么我们需要DDD(领域驱动设计)?

  通用语言:

    领域专家和开发者一起工作,大家使用通用的语言,能够精准地传达业务规则,减小误差。

  知识集中:

    在DDD中,每个人都在学习,同时每个人又是知识的贡献者,关键在于对知识的集中。

  设计代码:

    设计就是代码,代码就是设计。设计是关于软件如何工作的,最好的编码设计来自于多次试验。

  战略战术:

    DDD同时提供了战略设计和战术设计两种方式。战略帮助我们理解哪些投入是最重要的,战术则帮助我们创建DDD模型中各个组件。

使用DDD的业务价值

  有用的领域模型:DDD强调将精力花在对业务最有价值的东西上。我们并不过度建模,而是关注业务的核心域。获得一个非常有用的领域模型

  准确的业务规则:业务能够更好的理解业务本身,随着业务模型的不断改善,大家对业务得到更准确的定义和理解。

  更高的用户体验:用户体验可以更好地反应出领域模型的好还。软件不要留下太多地方让用户自己去理解,用户体验需要按照领域专家心中的模型来设计。

  清晰的模型边界:明确的目标产生搞笑的解决方案,而要达到这样的目的往往需要更好地理解项目的限界上下文。

  更好的企业架构:理解和划分限界上下文,当不同上下文的模型间存在依赖关系时,我们将使用上下文映射来集成不同限界上下文,有助于我们全面地了解整个企业的架构。

  战略战术新工具:限界上下文为团队创建了一个建模边界,使用上下文映射在战略层面上对限界上下文进行界分和集成。在某个边界内部使用战术建模工具。

原文地址:https://www.cnblogs.com/taotaozhuanyong/p/12731481.html