领域驱动设计之设计原则篇
语言从c的面向过程到java的面向对象,在程序设计、组织的角度来看是在抽象、直观化、便于模块整合上的一次进步。现在的许多通用框架,比如spring、mybatis为应用程序提供了对象的管理以及数据仓库的操作封装;对于一般规模的应用程序来说,业务模型与代码结构设计的重要性尚未凸显出来。但是如果业务复杂、涉及交互模块多,或者随着时间推进,需求和业务逻辑的变更、调整,将带来代码调整、辅助功能添加、原有设计修改,导致代码结构复杂、难以维护,损害代码的拓展性、健壮性以及对需求的响应速度。
当前盛行的敏捷开发是一种不错的解决方案,其中许多思想与领域驱动设计不谋而合,比如逐步迭代、演进、持续集成;实际上领域驱动是对敏捷开发的一个很好的补充,为敏捷开发中的设计、迭代演进提供模型设计、战略设计方法上的支持。
领域驱动设计,顾名思义,它是业务知识驱动的,但又不仅仅是按照业务人员的思路设计,因为设计最终还是要以应用程序的形式发挥作用,实际的开发者要与业务人员有充分的沟通、互动,如此才能设计出真正反应用户需求、适应需求变化的模型,甚至发现需求中更本质的矛盾以及核心点并推进产品演化。这听起来似乎很难,其实不然,只需要沟通充分、持续优化,是可实现的。任何一个流程或者设计,都是逐步演化、优化形成的,而非一蹴而就。好的流程、设计的原则很简单,只要它自然,不反人类。好的设计需要满足一些原则,以下是我从阅读《领域驱动设计:软件核心复杂性应对之道》后印象比较深刻的一些原则,下面对其做阐述以及发挥。
一、单一性。设计时最好头脑里只有一个最核心的点(概念),然后围绕它的核心活动、内容分析出子概念,事实证明这样的方法最简单,也最有效(有时会直达终点,突破已有知识的局限),比如在本书第8章中提到的例子中,由一步步分析、演化得到的突破,笔者通过直观的方式设计,直接与其最终效果一致。但是这种直观型的设计技巧需要一定的积累,首先是对现有业务知识的足够了解,其次对开发流程、经验有足够积累,最后模型设计的实战也要反复实践。在这个基础上,放空自己,从大脑中最直观的概念入手,往往能够得到最好的模型。
二、意图(语义)明确性。无论是控制器层、领域层,还是资源层(repository)的代码都要意图明确,而不要泛泛地都是findById,list之类的方法。要从语义概念上做模型划分。设计的内容是给人看的,所以要直观、易理解。要形成一套本模型的统一语言,专有的、反复打磨的概念将促进模型的明确化,及早发现冲突,并减少业务人员与开发之间的沟通成本。
判断明确性的一个指标可以是:让业务人员来看代码,在最顶层的几个方法级,不会陷入到各种细节的逻辑之中,而可以直接根据类名、方法名(包括在一个方法内出现的其他类、方法)看出业务的实现流程、思路。如此,在其他人接手或者重构时也可以很容易地上手。
在此,对一种先开发后重构的做法提一点意见,最好是先设计再开发,减少后期迭代重构时的工作量,也有更好的可维护性;即使在事后重构,也要从语义级别从上到下去整体思考领域以及相关职责,而不仅仅是提取公共方法块、公共逻辑,因为那样的重构对于其他人来说很难了解其意义,对于业务人员来说也形成不了可解释的流程、概念。
三、灵活性。架构的设计要为调整、转变(比如大结构从插件式组件,转为事件观察者模式)做准备,在关键点要做好便于切换的工作,架构是需要一步步验证、演化的;领域模型也是如此,一开始的领域边界不一定最合适,在开发中我们会发现新的领域边界,要以一定的形式反映出这些边界,所谓的概念轮廓。
软件设计上有开闭原则,对修改关闭,对拓展开启。好的设计应足够周到,减少修改,又要考虑可能的修改变化点,预备好拓展。对于业务人员来说,我们设计时的一些概念,比如库存中有所谓镜像库存、实际库存、理论库存,而我们有一个库存更新业务类,又有一个库存库存更新触发器类,就可以反映到代码结构上,让阅读者可以有一个形象、明确的概念、印象。
四、一致性。一致性反应在模型、代码工程上,有总体结构与子领域结构的协调、一致性,有编码风格以及团队合作方式的一致性;团队划分、合作方式也可以在模型关系上加以体现。领域驱动的设计不仅仅是上层人员的主观发挥,更要与底层的实现方式、团队、流程协调,这样才能真正促进开发,也才能真正得到有效的实践。一致性可以简化许多工作,并且会有协调一致之美,比如tomcat生命周期模型的观察者(事件监听器)模式,java io的装饰器模式。
五、自发性、演化性。好的模型、好的流程往往是自发的,而非预先的安排、指定。要设计一个好架构,不仅仅要通读已有的业务文档,还要与业务专家沟通,与底层开发人员沟通;在设计好模型、大型结构之后,需要持续跟进底层使用人员的反馈,甚至参与到他们的讨论、开发中,来得到对模型、设计的切实体会,进一步演化模型。所以,一开始不应该把结构设计得太死,设计的架构要尽量轻、尽量简洁、克制;这里提到的克制是这样的含义,在设计时对于业务、模型要有足够的演练、规划设想,但是具体成文指定、要求的部分却要仅仅选择充分确定且必要的内容。
开发流程的建立也是如此,甚至组织结构、角色的产生也应如此。团队中主导领域规划、总体流程设计、确定风格的人也能够自发产生,而且往往比从上层直接指定来得更科学、更有实效。
上面是对设计原则的一些分析,下面对其继续延伸,讲讲其中反映的影响项目、产品成功的团队文化因素。
一、沟通,团队内有不同职责、工作内容的人,比如业务人员、分析人员、开发、架构师等等,当面对一个产品的开发工作时,每个人都有自己的任务要完成,并且要有自己的产出;而不同角色之间的工作也是相互依赖的,比如分析人员需要分析业务人员提出的需求,开发需要根据分析人员得出的模型来设计实现方式并进行实际开发,架构师则要设计项目的结构、做技术选型。只有通过充分沟通,开发才能真正理解业务所要的成果以及他们所描述的一些关键概念,架构师才能设计出便于开发实现、反映业务、适应拓展的结构。
这里的沟通,是对角色、个人职责界限的打破,需要在以下两个基础上进行:
1、建立服务者心态、平等心态。比如架构师团队要把自己摆在辅助、帮助开发团队优化模型的角度,而不是仅仅做所谓设计,应该抱着跟进架构使用情况、了解开发日常开发工作中碰到的问题的态度去与开发沟通。书中提到的一个架构师团队,定期让不同的成员去开发团队中参与开发,以有实际、切身的体会,就是一个不错的方式。
甚至项目的总体负责人,也不要把自己放在顶端把控的位置上。而应该带着协调、观察者的心态,到开发、讨论、设计的现场,看他们的各种讨论、设计是否脱离自己的预期、规划,看他们流程中存在的实际问题,看各个团队的合作协调程度,看产品是否真正反映出公司的战略意图,看团队内的上下沟通协调气氛;以一个辅助者、服务者的心态,去融入团队。
2、明确愿景、目标。所有人的目标都是为了产出更好的产品,更好地解决用户需求。不仅仅关注自己的产出是否完成,是否出色,更要跟进使用到自己产出内容的人,根据他们的反馈不断调整、优化自己的产出;所有人都需要知道项目最重要的信息,包括愿景目标和最新模型。
二、求实。一切的工作都是为了实际落地、真正产生作用,而不仅仅是完成工作。领域驱动设计中处处体现了这个原则,比如要求业务、模型、代码实现高度一致,比如所有人员都使用统一语言进行沟通,从而及早发现模型中的问题,比如开发要充分了解业务,而架构设计则要充分考虑开发的实际实现场景;一切的一切都是为了尽可能减少工作阻力,将力气都花在有用的地方:对业务的不断深入理解,对产品的持续优化。
接下来分享一些实践:
领域驱动设计(DDD)在美团点评业务系统的实践
白话分布式定时任务框架
self4j日志框架设计之从无到有(结合logback的实现)
rpc框架简易实现
nio实战之netty实现
最后提供该书的下载地址(要积分):
领域驱动设计:软件核心复杂性应对之道_修订版.pdf(实际上是未修订版)
领域驱动设计之设计原则篇相关推荐
- yang模型中rpc_领域驱动模型(DDD)设计讲解
一. 什么是领域驱动模型(DDD)? 领域驱动模型一种设计思想,我们又称为DDD设计思想.是一种为了解决传统设计思想带来的维护困难,沟通困难和交互困难而产生的一种新的思想.也解决了在部分公司中,一个项 ...
- DDD领域驱动设计-分层架构实践
代码结构 项目是使用maven构建的springboot项目 基于DDD领域驱动分层架构设计,分为接口层interfaces.应用层application.领域层domain.基础设施代理层infra ...
- 走向卓越,领域驱动设计的思维方式
作者:程序之心丁仪 来源:https://chengxuzhixin.com/blog/post/ling_yu_qu_dong_she_ji_de_si_wei_fang_shi.html 软件系统 ...
- 领域驱动设计之CQRS
1.概念 CQRS全称:Command Query Responsibility Segregation ,中文名:命令查询与职责分离 2.什么是CQRS CQRS 将系统中的操作分为两类,即「命令」 ...
- 领域驱动应对业务复杂度
领域驱动应对业务复杂度 之前的文章提到过,领域驱动设计分成战略层次和战术层次,战略层次我们讨论的很多了,接下来我们主要看下战术层次要搞哪些事情,以及领域驱动如何以架构的形式落地呢. 分层架构 在进行软 ...
- 基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则
前言 上一篇 基于ABP落地领域驱动设计-01.全景图 概述了DDD理论和对应的解决方案.项目组成.项目引用关系,以及基于ABP落地DDD的通用原则.从这本篇开始,会更加深入地介绍在基于 ABP Fr ...
- .NET领域驱动设计—初尝(原则、工具、过程、框架)
阅读目录: 1.原则 1.1.精简聚合 1.2.分离用例与接口功能(设计模式的用武之地) 2.工具.框架.组件 3.过程 1]原则 原则对于任何一项技术实现来说都是至关重要的,在设计某一个系统功能的时 ...
- 领域驱动设计-原理心得篇
"最初我给本文起的标题是<领域驱动设计-理论入门篇>,但是文中掺杂了太多的个人理解,入门篇就显得太官方了,为了避免错误的理解把读者带偏,所以改成<领域驱动设计-理论心得篇& ...
- 什么是DDD(领域驱动设计)? 这是我见过最容易理解的一篇关于DDD 的文章了
领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...
最新文章
- 转载 用python 获取当前时间
- 辽宁鞍山与中国联通签订智慧城市大数据云计算中心项目
- 我的jQuery动态表格插件二
- 1093 Count PAT‘s (25 分)【难度: 一般 / 知识点: 前缀和 组合数】
- mysql select into和insert into select
- python读取大文件的某行_Python按行读取文件的实现方法【小文件和大文件读取】...
- Android 第五课 常用控件的使用方法(TextView、Button、EditView、 ImageView、 ProgressBar、 ProgressDialog等)
- 【状压dp】AC Challenge
- telnet 的使用(ping 与 telnet)
- 如何本地加载live2d模型 离线方式加载看板娘
- python创意小作品代码-超全代码详解 Python 制作精美炫酷图表教程
- Http方式下载文件
- 面试想不带简历,老罗可以,你不行!
- 调起百度地图客户端之导航功能
- MySQL 安全审计、容灾备份、数据恢复
- Matplotlib系列(五):三维绘图
- 如何利用PyTorch实现一个Encoder-Decoder结构进行英法互译
- 快捷餐饮之店家后台OSS文件管理实现
- linux内核:时间与jiffes互相转换
- 电脑端如何访问手机SD卡中的文件
热门文章
- 轻量级网络论文精度笔记(三):《Searching for MobileNetV3》
- 计算机电源多低无法使用吗,电脑电源功率不足现象和解决方法
- 河南邮政共享广告启动会圆满举办 华宝共享广告新经济迈向新起点
- 简单的福彩双色球生成器
- 分词算法 SmoothNLP
- win10扩展显示屏时遇到“Input signal out of range”
- MapReduce知识点(3)
- 在Spotify使用深度学习做音乐推荐(Recommending music on Spotify with deep learning)
- ios uitableviewcell 添加uibutton无法Highlighted问题
- Know Your Enemy