语言从c的面向过程到java的面向对象,在程序设计、组织的角度来看是在抽象、直观化、便于模块整合上的一次进步。现在的许多通用框架,比如spring、mybatis为应用程序提供了对象的管理以及数据仓库的操作封装;对于一般规模的应用程序来说,业务模型与代码结构设计的重要性尚未凸显出来。但是如果业务复杂、涉及交互模块多,或者随着时间推进,需求和业务逻辑的变更、调整,将带来代码调整、辅助功能添加、原有设计修改,导致代码结构复杂、难以维护,损害代码的拓展性、健壮性以及对需求的响应速度。

当前盛行的敏捷开发是一种不错的解决方案,其中许多思想与领域驱动设计不谋而合,比如逐步迭代、演进、持续集成;实际上领域驱动是对敏捷开发的一个很好的补充,为敏捷开发中的设计、迭代演进提供模型设计、战略设计方法上的支持。

领域驱动设计,顾名思义,它是业务知识驱动的,但又不仅仅是按照业务人员的思路设计,因为设计最终还是要以应用程序的形式发挥作用,实际的开发者要与业务人员有充分的沟通、互动,如此才能设计出真正反应用户需求、适应需求变化的模型,甚至发现需求中更本质的矛盾以及核心点并推进产品演化。这听起来似乎很难,其实不然,只需要沟通充分、持续优化,是可实现的。任何一个流程或者设计,都是逐步演化、优化形成的,而非一蹴而就。好的流程、设计的原则很简单,只要它自然,不反人类。好的设计需要满足一些原则,以下是我从阅读《领域驱动设计:软件核心复杂性应对之道》后印象比较深刻的一些原则,下面对其做阐述以及发挥。

一、单一性。设计时最好头脑里只有一个最核心的点(概念),然后围绕它的核心活动、内容分析出子概念,事实证明这样的方法最简单,也最有效(有时会直达终点,突破已有知识的局限),比如在本书第8章中提到的例子中,由一步步分析、演化得到的突破,笔者通过直观的方式设计,直接与其最终效果一致。但是这种直观型的设计技巧需要一定的积累,首先是对现有业务知识的足够了解,其次对开发流程、经验有足够积累,最后模型设计的实战也要反复实践。在这个基础上,放空自己,从大脑中最直观的概念入手,往往能够得到最好的模型。

二、意图(语义)明确性。无论是控制器层、领域层,还是资源层(repository)的代码都要意图明确,而不要泛泛地都是findById,list之类的方法。要从语义概念上做模型划分。设计的内容是给人看的,所以要直观、易理解。要形成一套本模型的统一语言,专有的、反复打磨的概念将促进模型的明确化,及早发现冲突,并减少业务人员与开发之间的沟通成本。
      判断明确性的一个指标可以是:让业务人员来看代码,在最顶层的几个方法级,不会陷入到各种细节的逻辑之中,而可以直接根据类名、方法名(包括在一个方法内出现的其他类、方法)看出业务的实现流程、思路。如此,在其他人接手或者重构时也可以很容易地上手。
      在此,对一种先开发后重构的做法提一点意见,最好是先设计再开发,减少后期迭代重构时的工作量,也有更好的可维护性;即使在事后重构,也要从语义级别从上到下去整体思考领域以及相关职责,而不仅仅是提取公共方法块、公共逻辑,因为那样的重构对于其他人来说很难了解其意义,对于业务人员来说也形成不了可解释的流程、概念。

三、灵活性。架构的设计要为调整、转变(比如大结构从插件式组件,转为事件观察者模式)做准备,在关键点要做好便于切换的工作,架构是需要一步步验证、演化的;领域模型也是如此,一开始的领域边界不一定最合适,在开发中我们会发现新的领域边界,要以一定的形式反映出这些边界,所谓的概念轮廓。
       软件设计上有开闭原则,对修改关闭,对拓展开启。好的设计应足够周到,减少修改,又要考虑可能的修改变化点,预备好拓展。对于业务人员来说,我们设计时的一些概念,比如库存中有所谓镜像库存、实际库存、理论库存,而我们有一个库存更新业务类,又有一个库存库存更新触发器类,就可以反映到代码结构上,让阅读者可以有一个形象、明确的概念、印象。

四、一致性。一致性反应在模型、代码工程上,有总体结构与子领域结构的协调、一致性,有编码风格以及团队合作方式的一致性;团队划分、合作方式也可以在模型关系上加以体现。领域驱动的设计不仅仅是上层人员的主观发挥,更要与底层的实现方式、团队、流程协调,这样才能真正促进开发,也才能真正得到有效的实践。一致性可以简化许多工作,并且会有协调一致之美,比如tomcat生命周期模型的观察者(事件监听器)模式,java io的装饰器模式。

五、自发性、演化性。好的模型、好的流程往往是自发的,而非预先的安排、指定。要设计一个好架构,不仅仅要通读已有的业务文档,还要与业务专家沟通,与底层开发人员沟通;在设计好模型、大型结构之后,需要持续跟进底层使用人员的反馈,甚至参与到他们的讨论、开发中,来得到对模型、设计的切实体会,进一步演化模型。所以,一开始不应该把结构设计得太死,设计的架构要尽量轻、尽量简洁、克制;这里提到的克制是这样的含义,在设计时对于业务、模型要有足够的演练、规划设想,但是具体成文指定、要求的部分却要仅仅选择充分确定且必要的内容。
       开发流程的建立也是如此,甚至组织结构、角色的产生也应如此。团队中主导领域规划、总体流程设计、确定风格的人也能够自发产生,而且往往比从上层直接指定来得更科学、更有实效。

上面是对设计原则的一些分析,下面对其继续延伸,讲讲其中反映的影响项目、产品成功的团队文化因素。

一、沟通,团队内有不同职责、工作内容的人,比如业务人员、分析人员、开发、架构师等等,当面对一个产品的开发工作时,每个人都有自己的任务要完成,并且要有自己的产出;而不同角色之间的工作也是相互依赖的,比如分析人员需要分析业务人员提出的需求,开发需要根据分析人员得出的模型来设计实现方式并进行实际开发,架构师则要设计项目的结构、做技术选型。只有通过充分沟通,开发才能真正理解业务所要的成果以及他们所描述的一些关键概念,架构师才能设计出便于开发实现、反映业务、适应拓展的结构。
     这里的沟通,是对角色、个人职责界限的打破,需要在以下两个基础上进行:
     1、建立服务者心态、平等心态。比如架构师团队要把自己摆在辅助、帮助开发团队优化模型的角度,而不是仅仅做所谓设计,应该抱着跟进架构使用情况、了解开发日常开发工作中碰到的问题的态度去与开发沟通。书中提到的一个架构师团队,定期让不同的成员去开发团队中参与开发,以有实际、切身的体会,就是一个不错的方式。
      甚至项目的总体负责人,也不要把自己放在顶端把控的位置上。而应该带着协调、观察者的心态,到开发、讨论、设计的现场,看他们的各种讨论、设计是否脱离自己的预期、规划,看他们流程中存在的实际问题,看各个团队的合作协调程度,看产品是否真正反映出公司的战略意图,看团队内的上下沟通协调气氛;以一个辅助者、服务者的心态,去融入团队。
      2、明确愿景、目标。所有人的目标都是为了产出更好的产品,更好地解决用户需求。不仅仅关注自己的产出是否完成,是否出色,更要跟进使用到自己产出内容的人,根据他们的反馈不断调整、优化自己的产出;所有人都需要知道项目最重要的信息,包括愿景目标和最新模型。

二、求实。一切的工作都是为了实际落地、真正产生作用,而不仅仅是完成工作。领域驱动设计中处处体现了这个原则,比如要求业务、模型、代码实现高度一致,比如所有人员都使用统一语言进行沟通,从而及早发现模型中的问题,比如开发要充分了解业务,而架构设计则要充分考虑开发的实际实现场景;一切的一切都是为了尽可能减少工作阻力,将力气都花在有用的地方:对业务的不断深入理解,对产品的持续优化。

接下来分享一些实践:

领域驱动设计(DDD)在美团点评业务系统的实践

白话分布式定时任务框架

self4j日志框架设计之从无到有(结合logback的实现)

rpc框架简易实现

nio实战之netty实现

最后提供该书的下载地址(要积分):

领域驱动设计:软件核心复杂性应对之道_修订版.pdf(实际上是未修订版)

领域驱动设计之设计原则篇相关推荐

  1. yang模型中rpc_领域驱动模型(DDD)设计讲解

    一. 什么是领域驱动模型(DDD)? 领域驱动模型一种设计思想,我们又称为DDD设计思想.是一种为了解决传统设计思想带来的维护困难,沟通困难和交互困难而产生的一种新的思想.也解决了在部分公司中,一个项 ...

  2. DDD领域驱动设计-分层架构实践

    代码结构 项目是使用maven构建的springboot项目 基于DDD领域驱动分层架构设计,分为接口层interfaces.应用层application.领域层domain.基础设施代理层infra ...

  3. 走向卓越,领域驱动设计的思维方式

    作者:程序之心丁仪 来源:https://chengxuzhixin.com/blog/post/ling_yu_qu_dong_she_ji_de_si_wei_fang_shi.html 软件系统 ...

  4. 领域驱动设计之CQRS

    1.概念 CQRS全称:Command Query Responsibility Segregation ,中文名:命令查询与职责分离 2.什么是CQRS CQRS 将系统中的操作分为两类,即「命令」 ...

  5. 领域驱动应对业务复杂度

    领域驱动应对业务复杂度 之前的文章提到过,领域驱动设计分成战略层次和战术层次,战略层次我们讨论的很多了,接下来我们主要看下战术层次要搞哪些事情,以及领域驱动如何以架构的形式落地呢. 分层架构 在进行软 ...

  6. 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则

    前言 上一篇 基于ABP落地领域驱动设计-01.全景图 概述了DDD理论和对应的解决方案.项目组成.项目引用关系,以及基于ABP落地DDD的通用原则.从这本篇开始,会更加深入地介绍在基于 ABP Fr ...

  7. .NET领域驱动设计—初尝(原则、工具、过程、框架)

    阅读目录: 1.原则 1.1.精简聚合 1.2.分离用例与接口功能(设计模式的用武之地) 2.工具.框架.组件 3.过程 1]原则 原则对于任何一项技术实现来说都是至关重要的,在设计某一个系统功能的时 ...

  8. 领域驱动设计-原理心得篇

    "最初我给本文起的标题是<领域驱动设计-理论入门篇>,但是文中掺杂了太多的个人理解,入门篇就显得太官方了,为了避免错误的理解把读者带偏,所以改成<领域驱动设计-理论心得篇& ...

  9. 什么是DDD(领域驱动设计)? 这是我见过最容易理解的一篇关于DDD 的文章了

    领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...

最新文章

  1. 转载 用python 获取当前时间
  2. 辽宁鞍山与中国联通签订智慧城市大数据云计算中心项目
  3. 我的jQuery动态表格插件二
  4. 1093 Count PAT‘s (25 分)【难度: 一般 / 知识点: 前缀和 组合数】
  5. mysql select into和insert into select
  6. python读取大文件的某行_Python按行读取文件的实现方法【小文件和大文件读取】...
  7. Android 第五课 常用控件的使用方法(TextView、Button、EditView、 ImageView、 ProgressBar、 ProgressDialog等)
  8. 【状压dp】AC Challenge
  9. telnet 的使用(ping 与 telnet)
  10. 如何本地加载live2d模型 离线方式加载看板娘
  11. python创意小作品代码-超全代码详解 Python 制作精美炫酷图表教程
  12. Http方式下载文件
  13. 面试想不带简历,老罗可以,你不行!
  14. 调起百度地图客户端之导航功能
  15. MySQL 安全审计、容灾备份、数据恢复
  16. Matplotlib系列(五):三维绘图
  17. 如何利用PyTorch实现一个Encoder-Decoder结构进行英法互译
  18. 快捷餐饮之店家后台OSS文件管理实现
  19. linux内核:时间与jiffes互相转换
  20. 电脑端如何访问手机SD卡中的文件

热门文章

  1. 轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
  2. 计算机电源多低无法使用吗,电脑电源功率不足现象和解决方法
  3. 河南邮政共享广告启动会圆满举办 华宝共享广告新经济迈向新起点
  4. 简单的福彩双色球生成器
  5. 分词算法 SmoothNLP
  6. win10扩展显示屏时遇到“Input signal out of range”
  7. MapReduce知识点(3)
  8. 在Spotify使用深度学习做音乐推荐(Recommending music on Spotify with deep learning)
  9. ios uitableviewcell 添加uibutton无法Highlighted问题
  10. Know Your Enemy