领域驱动设计,让程序员心中有码(二)

 引子,软件工程没有银弹

     上一篇博文领域驱动设计,让程序员心中有码,抛出了一个问题,领域驱动设计真的是万能的良方吗?对于这个问题,大家的答案无疑是一致的,作为一种非常受软件行业欢迎的软件思想,领域驱动设计固然有很多优点,却并非万能。

   回到十年前,第一节软件工程学的课堂上,我们的老师就告诉了我们一句真理,软件工程没有银蛋,这句话说的是,软件工程领域,从来没有一种思想或理论能够带来成倍的效率提升。不知不觉,十年过去,我们大概可以看到,软件开发新技术日新月异,新语言层出不穷,但是无论哪种技术,都不见得相对于其所对标的技术取得了成倍的提升。技术尚且如此,理论就更不用说了。

   领域驱动设计,近年来受到技术圈的广泛追捧,主要得益于微服务技术的发展。一千个读者有一千个哈姆雷特,而不同的人往往对这种理论有不同的看法。如果问一个.net开发者领域驱动是什么,大概他会说是abp架构。ABP架构作为完全按照领域驱动设计思想构建的技术架构,目前得到了社区的广泛追捧。然而,领域驱动架构和领域驱动设计,依然是道和术的区别,开发者在学习领域驱动架构的同时,也应该了解领域驱动设计。那么领域驱动设计究竟是什么的东西?由于时间和篇幅有限,我无意通过代码介绍如何实现一个领域驱动的功能,而是希望把领域驱动设计的基本思路进行梳理,期待能通过我的梳理,抛砖引玉,给大家带来启迪

    一,领域驱动设计,不错的选择  

  作为现代软件工业发展的产物,敏捷开发和极限编程,实现了生产力的解放,通过抛弃传统研发模式中留下的臃肿的设计文档,实现了劳动生产力的提升,无数互联网公司,依靠灵活的开发手段,为产品插上了快速开发的翅膀。开发者们不用加班,分分钟就把代码撸完,然后把产品质量关把好,发布,嗯,早早的就回家休息了。然而,随着产品功能的逐渐增加,团队自然而然也需要扩展。可是,团队成员越来越多,代码质量成为一个难以把控的问题。如何保证产品功能的一致性?如何保证功能符合产品的需求?管理者们不厌其烦,每天开会必须提开发质量,必须强调变量命名,注释,设计原则,设计模式,然后每天一次集成,代码审查估计已经不现实了。于是,作为面子的产品质量尚且有测试把关,而作为内脏的代码质量本身,成为上帝的骰子,好与坏全靠开发者们的自觉性和经验。

640?wx_fmt=png

    冰山,在软件产品华丽外表之下,究竟深藏着多少问题?

一个复杂的数据库关系模型图 

  领域驱动设计在这样的场景下推出来的一种理念。软件系统的复杂度是开发者们没办法避免的客观情况,而根据领域的实际情况,建立模型是解决问题行之有效的方法。在实际过程中,我们需要领域专家与开发者一起,共同努力,以一种特殊的方式来进行沟通,并通过模型将实际生活中的问题抽象化。 
  领域驱动设计的核心是建模,实际上对于大部分开发者而言,建模是一个基本技能,却并非每个人都能熟练的掌握。技术人员都普遍对他们工作领域有关的知识不感兴趣,而更愿意从事精细的框架工作,例如通过技术手段解决实际问题。而学习业务领域和领域建模的工作往往留给别人去做。然而,实际上,软件核心的复杂性,既包括需要直接面对的技术问题,而客观存在的业务问题却也是不可忽视的,过份重视技术,轻视建模,只会导致工作重心的偏离。甚至可以说,过份的重视领域驱动架构基础设施本身,而忽略了建模过程,在后期执行过程中可能会导致不可控制的风险。对于这一点大家都是容易理解的,以前的架构,简单反而容易维护,而系统架构复杂了,反而提高了学习成本导致不容易维护。 
  软件设计的基本原则是“高内聚,低耦合”。作为一个复杂的软件工程,依靠领域驱动建模,将紧密联系在一起的业务设计成一个领域模型,让领域模型内部隐藏细节,这样让领域模型与领域模型之间的关系变得简单,将极大的降低复杂业务之间千丝万缕的耦合关系。 
  

640?wx_fmt=png

                        面向领域设计的模型图 
             二,领域设计的要素,统一语言和建模及文档
   在进行设计之前,我们有必要建立基本的原则,那就是统一语言,模型,和设计文档。 
  1  统一语言 
  在日常讨论过程中,我们需要跟领域专家讨论,往往大家都是自己行业内的专家,也意味着大家都有自己的表达问题的方式和自己的理解,这有可能导致需求支离破碎。例如对对方表达的术语不了解,会形成鸡同鸭讲的情况。因此,需要建立一个能够互相沟通理解的语言环境,例如,互相的交流双方的术语,并试图利用双方都能理解的词语进行问题的分析。也许在最开始这样共同语言并不能很好的运作,但是却可以在后期逐渐完善。我们的开发者应该定期的了解领域所在行业的业务知识,扩充自己的知识面,这也有利于我们与领域专家的交流。 
  2  建模和画图 
  在我们工作过程中模型无处不在,不管是在纸上绘制的简单模型,或者使用专业软件绘制的各种模型,都是模型。领域驱动设计本身,依然依赖于模型驱动设计。学会建模对于广大开发者来说,都是一项基本技能。可以说,代码语言是为了与其他开发者进行沟通交流,那我们建立的各种软件设计模型将极大的方便不同领域的人员进行交流。建模也可以称之为语言的一部分利用uml建立类图,是一种可以比较易于接受的方式。我们可以采用以下手段来建立领域模型。 
  1)建立一个与实现绑定的模型。初版的模型也许很简陋,但是它可以成为一个基础,然后在后期逐渐完善。 
  2)建立一种基于模型的通用语言或表达形式和机制。通过通用语言让参与项目的所有人理解模型。 
  3)开发一个蕴含丰富知识的模型。模型不是单纯的数据结构,它更是各类知识的聚合体。 
  4)提炼模型,模型应该能在项目过程中动态改变,发现新的概念就加进来,过时的概念就适时移除,避免臃肿。 
  5)头脑风暴和实验。模型在于实践和应用,它需要项目参与者共同的努力,而头脑风暴是发挥集体智慧的良好方式。对模型进行实验或者进行场景的模拟,有利于让模型更符合需求。 
  当然,对于领域专家而言,不同类型的模型也许无法理解,例如类图可能过于复杂,可以使用画图的形式,通过解释性的图形或者模型,可以让不同层次的人都能获得一致的理解。 
  3  设计文档 
  设计文档依然是不可抛弃的重要资料,虽然设计文档可能不利于维护,却仍然不可抛弃。毕竟开发过程中,通过代码和模型,有可能会导致关键信息的丢失,而且有的不能直接参与讨论的领域专家需要通过文档才能了解之前讨论的情况,甚至可能画图会形成很多歧义,这也需要解释性的文档才能说清楚。为了让文档变得更加有效,不建议重复赘述已知的信息,而关键信息更改后,应该尽量保持最新。 
完全依赖代码或架构的自解释特性目前似乎已经成为大家的普遍习惯,但是代码可能存在歧义,或者有的方法本身就无法表达方法的本质含义,最终导致代码成为无法理解的神之领域,这种问题已经不是一个单纯的领域驱动架构能够解决的。如果为了让代码来解释模型,我们所有人必须时刻抱着一丝不苟严于律己的态度,才能写出完全符合领域模型的代码,问题是这种方式现实吗? 
  4  概念总结: 
  1)领域就是问题域,有边界,领域中有很多问题; 
  2)任何一个系统要解决的那个大问题都对应一个领域; 
  3)通过建立领域模型来解决领域中的核心问题,模型驱动的思想; 
  4)领域建模的目标针对我们在领域中所关心的问题,即只针对核心关注点,而不是整个领域中的所有问题; 
  5)领域模型在设计时应考虑一定的抽象性、通用性,以及复用价值; 
  6)通过领域模型驱动代码的实现,确保代码让领域模型落地,代码最终能解决问题; 
  7)领域模型是系统的核心,是领域内的业务的直接沉淀,具有非常大的业务价值; 
  8)技术架构设计或数据存储等是在领域模型的外围,帮助领域模型进行落地; 
    三、问题思考

  掌握建模和基本的步骤,意味着一切刚刚开始。道阻且长,行则将至,领域驱动设计,不仅仅是一种简单的建模思想或技术架构,更是一种挑战。在选择之前,是否需要思考一下,这一套体系,真的适合在你的团队中运行么?如果要切实的运行,还需要付出多少代价?尤其是对于领域模型而言,如果缺乏合理有效、而且持续迭代的设计,你难道不觉得最终所有的模型仅仅只是一种数据结构设计吗? 
参考资料: 
1.《领域驱动设计-软件核心复杂性应对之道》 
2.
https://blog.csdn.net/three_bird/article/details/51336834 
3.
https://blog.csdn.net/heweimingming/article/details/78661540

原文地址: https://www.cnblogs.com/xiyuanMore/p/10085784.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318583.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bzoj#2407-探险【最短路,二进制分组】

正题 题目链接:https://darkbzoj.tk/problem/2407 题目大意 nnn个点的一张无向图(但是正反权值不同),求一个从111出发回到111且不经过重复边的最短路径。 1≤n≤10000,1≤m≤21051\leq n\leq 10000,1\leq m\leq 2\times 10^51≤n≤10000,1≤…

The 2020 ICPC Asia Macau Regional Contest A. Accelerator(分治+NTT)

A. Accelerator 实质上就是求n个多项式相乘 (a1x)(a2x)…(anx)(a_1x)(a_2x)\dots(a_nx) (a1​x)(a2​x)…(an​x) 对于[xm][x^m][xm]的系数即是从nnn个选出n−mn-mn−m的乘积之和。 每次从nnn个选出n−mn-mn−m的概率显然为 (nm)n!\frac{\binom{n}{m}}{n!} n!(mn​)​ 然后期…

牛客题霸 [栈和排序] C++题解/答案

牛客题霸 [栈和排序] C题解/答案 题目描述 给你一个1->n的排列和一个栈,入栈顺序给定 你要在不打乱入栈顺序的情况下,对数组进行从大到小排序 当无法完全排序时,请输出字典序最大的出栈序列 题解: 栈的性质是先进后出 当栈…

邮局-[IOI2000](四边形不等式)

概要 四边形不等式的核心在于缩小最优转移的范围 题目描述 传送门 解析 这道题说是不等式,但其实也可以感性理解 (其实就是不想证明) 定义pl[i][k]: i到n的村庄建造k座邮局时,第一座管辖的范围是i-pl[i][k] (也就是最优决策…

.NET Core实战项目之CMS 第九章 设计篇-白话架构设计

前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了。今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的《从零开始学架构》里面关于架构设计的定义以及架构设计的三大原则,希望能对大…

P6847-[CEOI2019]Magic Tree【dp,线段树合并】

正题 题目链接:https://www.luogu.com.cn/problem/P6847 题目大意 nnn个点的一棵树上,每个时刻可以割掉一些边,一些节点上有果实表示如果在did_idi​时刻这个点恰好不与111联通,那么就可以获得wiw_iwi​的价值。 1≤n,k≤1051\leq n,k\leq 1…

P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​&#xff1a;c 在点 a 的子树中&#xff0c;根据乘法原理计算答案为 min⁡(deepa,k)∗(sza−1)\min(\text{deep}_a,k)∗(\text{sz}_a−1)min(deepa​,k)∗(sza​−1)若 deepb>…

树链剖分-学习报告

概要 &#xff08;这是笔者刚学完趁热写的博客 由于也是初学&#xff0c;所以可能会对初学读者比较友好吧 毕竟你不明白的地方我可能也迷惑过&#xff09; 学完感觉树链剖分的设计真的很巧妙 其主要用途是压缩树上路径 又是一个n到log的优化 原理 先引定义&#xff1a; 设…

牛客题霸 [拼接所有的字符串产生字典序最小的字符串] C++题解/答案

牛客题霸 [拼接所有的字符串产生字典序最小的字符串] C题解/答案 题目描述 给定一个字符串的数组strs&#xff0c;请找到一种拼接顺序&#xff0c;使得所有的字符串拼接起来组成的字符串是所有可能性中字典序最小的&#xff0c;并返回这个字符串。 题解&#xff1a; 用sort…

今日头条Marketing API小工具(.Net Core版本)

前言由于工作原因&#xff0c;需要用到今日头条的Marketing API做一些广告投放的定制化开发。然后看现在网上也没多少关于头条Marketing API的文章&#xff0c;于是便就有了该篇文章。头条Marketing API主页地址&#xff1a;https://ad.toutiao.com/openapi/index.html。头条Ma…

P6880-[JOI 2020 Final]オリンピックバス【最短路】

正题 题目链接:https://www.luogu.com.cn/problem/P6880 题目大意 给出nnn个点mmm条边的有向图&#xff0c;边有边权和一个翻转权值。 翻转至多一条边使得1−>n−>11->n->11−>n−>1往返的权值加上翻转权值最小。 1≤n≤200,1≤m≤51041\leq n\leq 200,1\…

The 2020 ICPC Asia Macau Regional Contest J. Jewel Grab(数颜色+链表)

J. Jewel Grab Tartarus _Wallace_ 转化询问&#xff1a;对于一个询问 [s,k]&#xff0c;找到一个最长的区间 [s,t]&#xff0c;满足区间中出现次数超过一次的元素&#xff0c;的出现次数减一&#xff0c;的和&#xff0c;不超过 k。 对于该区间[s,t] 区间数颜色&#xff1a;…

牛客题霸 [最大数] C++题解/答案

牛客题霸 [最大数] C题解/答案 题目描述 给定一个数组由一些非负整数组成&#xff0c;现需要将他们进行排列并拼接&#xff0c;使得最后的结果最大&#xff0c;返回值需要是string类型 否则可能会溢出 题解&#xff1a; 将字符串存入vector中然后sort排序&#xff0c;最后将…

模板:割点、桥与双连通

文章目录割点代码桥点双连通分量代码边双连通分量代码割点 和强连通分量十分相似 分为树枝边、前向边和后向边 注意&#xff01; if(x!r&&low[to]>dfn[x]) cut[x]1;这句判断只能在树枝边出现 否则会因为前向边的存在而出错 代码 #include<bits/stdc.h> us…

.NET Core实战项目之CMS 第十章 设计篇-系统开发框架设计

这两天比较忙&#xff0c;周末也在加班&#xff0c;所以更新的就慢了一点&#xff0c;不过没关系&#xff0c;今天我们就进行千呼万唤的系统开发框架的设计。不知道上篇关于架构设计的文章大家有没有阅读&#xff0c;如果阅读后相信一定对架构设计有了更近一部的理解&#xff0…

喝酒、工作与自律

喝酒 自从开始打算品酒之后&#xff0c;家里的小酒数量不断增加&#xff0c;每天晚上喝个15ml&#xff0c;慢慢也能喝出一些区别了。 酱香、清香、浓香的区别还是挺明显的&#xff0c;闻香就能区别出来 浓香里的五粮液特点很明显&#xff0c;闻的时候有粮香&#xff0c;入口后…

51nod1836-战忽局的手段【期望dp,矩阵乘法】

正题 题目连接:http://www.51nod.com/Challenge/Problem.html#problemId1836 题目大意 nnn个点mmm次随机选择一个点标记&#xff08;可以重复&#xff09;&#xff0c;求最后被标记点的期望个数。 1≤n,m≤10181\leq n,m\leq 10^{18}1≤n,m≤1018 解题思路 额开始拿方案数推了…

分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0

今年五月的 Build 大会上&#xff0c;微软说 .NET Core 3.0 将带来 WPF / Windows Forms 这些桌面应用的支持。当然&#xff0c;是通过 Windows 兼容包&#xff08;Windows Compatibility Pack&#xff09;实现的。为了提前检查你的程序是否能在未来跑在 .NET Core 3.0 上&…

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明) Stone Games

Stone Games 主席树 Code1 #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N1000010; using lllong long; const ll MAX1000000000ll; int n,a[N],m; struct node {int l,r;ll v; }tree[N*40]; int root[N],c…

路径求和(ybtoj-树形dp)

文章目录题目描述解析代码题目描述 给出一棵带边权的树&#xff0c;求所有至少有一个端点为叶节点的所有简单路径的长度和 解析 换一个角度想 考虑将树分割为AB两部分的一条边会存在于多少条符合条件的路径中&#xff08;也就是边权会考虑多少次&#xff09; 不难发现&#…