.NET领域驱动设计—初尝(二:疑问、模式、原则、工具、过程、框架、实践)

 

  • 1.3.原则
    • 精简聚合
    • 分离用例与接口功能(设计模式的使用之地)
  • 1.4.工具、框架
  • 1.5.过程
  • 1.3】原则

    原则对于任何一项技术实现来讲都是相当重要的,在设计某一个系统功能的时候咱们讲究的是设计原则:数据库

  • 单一职责原则Single Responsibility Principle、里氏替换原则Liskov Substitution Principle、依赖倒置原则Dependence Inversion Principle、接口隔离原则Interface Segregation Principle、迪米特法则Law Of Demeter、开闭原则Open Close Principle】。设计模式

    在架构设计的时候咱们也讲究架构原则:架构

  • 【分层原则、避免循环依赖】。框架

    不只仅在技术领域在作人作事都要讲究原则,违背原则那么等待你的将是无情的惩罚。ide

    对于DDD的设计咱们也有相应的原则须要遵照,固然若是不遵照在前期看不出什么区别,可是到开发阶段问题就会暴露出来。工具

    咱们来看两个基本的设计原则问题。学习

    【精简聚合】编码

    精简聚合的设计原则无疑是最重要的。一些软件工程方法论书籍常常指导咱们进行UML业务建模,"在这个阶段不须要考虑任何技术实现问题”,我按照这样的指导原则进行了UML的设计而后顺利的建立出ER关系图,结果发现那样的数据库结构根本不能做为最终的项目开发数据库。哪里出问题了?我反复查询指导书籍后来在专业的DDD书籍上看到了一句大概这样的话:spa

    • 【“不以技术实现为前提的设计都是纸上谈兵”】架构设计

    我想这句话很真实的描述了方法论与企业应用之间的鸿沟,不少技术思想或者理论确实很好,可是要想用起来须要解决不少问题。DDD也避免不了这个问题,怎么避免在设计UML模型的时候不会致使设计过分的问题,这里咱们只须要遵照【精简聚合】原则就不会致使设计过分问题。

    在前面的例子当中咱们设计一个完整的UML领域模型,可是咱们并无对它进行【精简聚合】重构,因此它存在的问题就是没法进行项目开发。

    1.1图

    8

    咱们构建出来的领域模型初步版本应该是上图这样的,实体与实体之间是有强联系的,聚合之间的关联太大,致使牵一发而动全身。若是按照这种关系建立数据库那么数据库之间的主\外键确定不少,对数据库的设计形成了影响。这样的关系若是在程序中使用也会存在不少问题,咱们没法进行少数聚合的使用,当咱们使用某一个聚合的时候它会连续不断的把相关联的聚合都给拖出来,不只在查询的时候妨碍并且在Factory建立聚合的时候也会存在没法构造的问题,无论在对聚合Repository进行任何操做的时候都会影响程序逻辑,因此咱们须要对一个复杂的庞大的关系进行拆分。

    将红线的部分所有断开,聚合之间经过Id进行关联,这样就会变的很清晰。由于不多程序中会在某一个业务逻辑点上须要全部的业务模型参与,这样既方便了程序的开发也方便了数据库的设计,更方便了ORM的使用。ORM的延迟加载其实就是为了聚合之间的依赖,能够在须要的时候在去查询须要的模型。可是这样虽然程序能够说的过去,那么数据库的设计就说不过去了。对于不一样的ORM框架的映射原理不一样,在构造模型的时候是须要稍微的调整的,好比在EntityFramework中,它能支持的映射方案你保证你的模型能顺利的映射过去,这里就不扯了后面有一个详细的项目作全面实践,到时候在具体问题具体分析。[王清培版权全部,转载请给出署名]

    最后咱们看一下分解后的类图:

    1.2图

    9

    这样一来一块一块很清晰,都能直接使用相关的核心领域模型,也不须要担忧ORM框架的延迟加载的问题。

    【分离用例与功能接口(设计模式的使用之地)】

    分离用例与功能接口其实也是初次接触DDD的朋友都会犯的职业病,由于咱们都熟悉面向对象设计。在进行UML建模的时候咱们都很是喜欢抽象,会很清楚的把具备泛化关系的用继承来表示,好比【用户类型】,不一样的用户具备不一样的行为权限,在初步设计的时候咱们通常都会创建关于用户的一个继承关系来表达泛化的业务模型。可是在编码阶段会发现很明显的问题就是咱们把关于Repository的行为包含到了发起用例的用户聚合当中去了,这样说可能有点抽象。咱们仍是用例子来分析;

    1.3图

    10

    上图中我将【Admin】和【配送】用例分开了,想表达是不能将关于配送的行为放在【Admin】中。在咱们对有关权限进行建模的时候常常会潜意识的将各自的行为放在了各自的角色当中,若是后期存在多角色共享行为的就将写在抽象的类中使用虚方法向下传递。问题就出在关于角色行为里,咱们知道若是有行为那么就有可能在该行为里面执行有关其余聚合的IRepository操做,这样一来将会把领域模型搞的很乱,没法垂直分析。

    1.4图

    11

    DDD讲究领域驱动,在咱们看来【Dispatching】、【CheckOrders】都是继承管理员角色,管理员属于后台管理人员,意味着企业的员工。对消费者来讲他们就是管理人员。一样消费者也会存在相同的状况,消费者可能存在不少种类型,有VIP系列的(VIP1\VIP2\VIP3…),有钻石会员之类的。若是这样设计的话并不能说是错的,这也彻底符合DDD的思想要求,可是实际状况下倒是不理想的。

    这里就用到了咱们长期使用的设计模式了,咱们能够经过设计模式中的不少中模式来将用户与行为分离开来,再将使用的规则条件抽象出来就彻底独立了用户,用户在使用的时候不会存在直接的行为归属,可是事实上他们确实是有行为。

    1.5图

    12

    用专业的DDD术语讲“规约模式”,将业务规则抽取出来对象化,甚至到最后均可以进行规则的配置化。最让咱们兴奋的是,咱们苦心学习的设计模式终于能够在系统设计中大面积的使用了,难道不是一件很惊喜的事情吗!

  • 1.4】工具、框架

    任何一种架构都是须要框架、工具的支撑才能变的完美。

    当咱们在某种架构下进行开发的时候,咱们必须须要不少工具、框架的支撑才能让开发工做变的很便捷,这也和【敏捷开发】的思想同样。在传统的三层架构下开发咱们都须要 "对象映射"、"AOP\IOC” 等等相似的辅助框架,目的是为了架构前行的可能性。在DDD中咱们也须要不少目前尚未出现的不少工具、框架,在.NET平台中目前来看只有EntityFramework框架算是为了DDD作了不少工做,若是咱们的领域模型没法与数据库进行映射,那么领域模型开发所要付出的代价将是很大。

    在设计阶段咱们缺少一个面向特定领域的建模工具,这种工具与UML不一样,UML太技术化通用化。DDD中常常会提起【领域专家】一角,他是最具备权威性的领域领头人,咱们所建立出来的UML他们未必能看得懂,经过技术人员技术化以后造成UML其实已经变味,【领域专家】是懂非懂的没法作到确定的保证。若是能把领域模型语言化,那么这个将是一大成就。【领域专家】对领域中的任何事物、人物、环节都很熟悉,可是他没法表达清楚本身的想法,若是能有一个工具辅助他的设计,该工具能将设计后的模型进行平滑等价的技术化变成代码模型或者数据库模型,这一条鸿沟若是能跨越那么对行业来讲具备很大影响力。

    1.8图

    13

    若是咱们能等价的将上图中的真实模型进行技术化,那么真的每一个人都会喜欢需求分析、分析设计。

    既然是模型驱动设计,咱们在给用户分析相似这样一套系统的时候,前提是咱们已经对里面的全部细节进行了抽象封装,每个过程都是能够拆分的,最后能合并在一块儿造成一个总体的业务模型。固然这里只是一种技术展望,也是咱们奋斗和理想的目标。

    推荐一本最新Martin Fowler的书:《领域特定语言》

     

  • 1.5】过程

    DDD不是一种纯技术实现,而是一整套开发思想,它贯穿软件开发的全部生命周期。从咱们开发接触领域,对领域知识进行深刻的消化,这些都是DDD所强调的。那么在咱们平常开发过程当中,咱们该如何处理这些过程,需求不会再像之前那样是一份杂乱无章的草稿,而是一个内容丰富的领域模型草图。这样的要求对团队对部门甚至对公司来讲都是一个提高,要想作到彻底的DDD过程其实很难。

公司领导如何看待这样的开发方式,咱们多数人都是在一些非专业研发类的公司工做,领导但愿能尽早的看到东西,这很矛盾,须要好的东西可是不按照好的东西作法来作。若是有幸能有一个面向DDD、敏捷、XP的研发团队工做,那么能够视项目为一件终身的艺术品。[王清培版权全部,转载请给出署名]

 

这两篇文章主要是一些本人对DDD的感悟,分享给你们。

后面一篇文章将会详细的使用一个DDD架构的小系统做为案例给你们分享,里面将包括从需求的分析建模、设计模式的使用、数据库映射、EntityFramework的使用等等,能够做为真实项目开发的依据。

相关文章
相关标签/搜索