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

 领域驱动是十五年前,由Eric Evans提出的解决软件工程复杂性问题的方法,作者从自己多年软件开发的角度出发,通过引入领域驱动设计的概念以及一系列战略设计模式和战术方法,为混沌的软件开发领域带来了一缕阳光。

  在过去的许多年,我经历了从技术岗位到管理岗位的变化,也深深的意识到,每一个软件的设计与实施过程之艰辛,缺乏一些科学的管理方法,只会让人疲于奔命,毫无积累,尤其是对于开发过程而言,看似枯燥乏味的编码过程,却充满了更大的变数。

  例如,在以前传统企业开发中设计系统架构时,往往会使用三层架构,用户界面层,业务层,数据访问层上手就来,但是却看似三层分立,但是由于开发者开发过程中出现的一些不规范问题,容易在用户界面层和数据层中堆积大量的冗余代码,而中间的业务层反而非常单薄,代码行很少,仅仅只是实现对象的输出而已。用户界面层和数据访问层就很容易成为腐化代码,随着需求的变更,容易变成大泥球系统。

  尤其是那些核心模块的用户界面层代码,轻易就突破了上千行,甚至上万行,这些代码并非完全都是由于不规范的操作造成的,一定程度上也是由于个别开发者的代码不规范,形成的破窗效应。不管发生了什么,这些代码最终成为一座屎山。如果再加上古人写的存储过程,对不起,我选择自闭。

  屎山的命运往往都是一样的,要么重构成功,得以逆天改命,要么被公司抛弃,成为企业发展过程中的一座重要里程碑,要么跟着公司一起,成为创业者的黄粱美梦。 是什么造成了屎山?是需求吗?

需求控制或不控制?

  用户需求就像一个关在笼子里的狮子,控制或不控制,这是个问题。

  对于互联网公司而言,一定程度上来说,需求来源于产品经理的灵感乍现,或来源于对竞品(被抄袭品)功能的把握,不同产品经理对于产品的规划总是不尽相同,以及老板和用户的反馈也是产品需求变化的原因,需求的累积也会让开发者为了修改而疲于奔命,而且面向互联网的产品往往比项目型软件成品面向更大的群体,拥有更长的生存周期,开发者为了应对需求而不节制的更改,容易成为试错,甚至会影响企业的生存。

  所以使用领域驱动设计方法对后端的结构进行改造甚至中台化改造成为一种非常有效的解决方案,而对于面向用户的前台,以及为前台而生的BFF则由于更侧重于用户数据交互,而被排除于领域控制之外,(即 Backend For Frontend)(当然,过度的依赖前端表现层,也容易造成前端代码的冗余,事实上前端和客户端代码也最容易成为屎山,这是后话,就不赘述了。)

  除互联网公司需要领域驱动的方法外,传统软件企业也同样需要,在企业发展过程中,积累的无数项目,大部分项目都存在一些普遍性的共性,那就是为了盲目追求实现,而忽略了软件代码的健壮性和可维护性,能否把功能强推下去,取决于项目经理对于甲方的控制力,一旦掌握优秀沟通技巧的关键岗位离职,这些项目都将成为一个个不知何时会爆发的地雷。软件企业项目的复杂性,有别于互联网企业的面对业务快速裂变带来的变化,往往更侧重于业务层面的规模复杂,一个系统的大几百个功能点,如何保证质量,时间,成本三者的平衡,这是个恒古不变的问题。

  需求让软件充满变数、而规模、质量属性也同样会影响到软件的变化,要打破僵局,或许,领域驱动看似是一种不错的选择。

看似破解之道

  然而,领域驱动的实践过程却充满坎坷,主要在于 Evans的原书,知识密度之稠,远甚于开发者热衷的技术话题。要解决某些技术问题,依托互联网的资源,或许能很快找到解决问题的方法,但是面对领域驱动设计,却让人望而生畏,许多人都说虽然听说这个概念的时间不在短暂,但是却总觉得没有入门。

  单纯的从概念上看,引入的统一语言,领域存储库,实体,值对象,聚合根,限界上下文,上下文映射等名词,理解上似乎很容易,但是要付诸实践却并非易事。尤其还需要把这些东西引入到企业实战过程,更是难上加难。领域驱动设计方法,并不像那些技术书籍一般,拿着书上的方法,总能在自己公司找到可以实践的点。 Evans的书也好,其他书也好,都只是方法,而不是一套行之有效,马上就能使用的方案,需要团队花费大量时间去应用实践。

  例如,一种最常见的领域驱动架构的实践是简单四层的领域驱动分层结构,在不能有效理解关注度分离的前提下,架构代码同样能成为屎山,而且似乎由于开发者知识传承的缺失,极其容易让人难以理解和更不用说代码质量的提升,只能成为倡导者实现个人价值提升的练兵场。

640?wx_fmt=png

个人想法

  我个人认为,领域驱动设计方法,作为一种解决复杂问题的应对之道,确实值得企业对其持续关注,但是否有一种能够便捷的方法,让参与者能够更快的将这么好的方法论在产品研发过程中融汇贯通,形成更高效的应用过程呢,下面是我根据一些讨论和学习过程,形成的一点思考,希望能给大家带来一丝启发。

  1,如何开始改变企业文化?这是来自于《实例化需求》中提出的一个问题,作者的原意是认为要实践TDD,需要进行文化变革,事实上实践DDD或许同样如此。康威定律指出:一个组织拿出的技术方案设计,实际上是一个组织沟通方式的体现。你的组织真的准备好开始接受这种思想的考验了吗?这是个问题。

  2、确保你得到管理层的支持。这也是来自于《实例化需求》中的原话,毫无疑问,如果缺乏管理层的认可和支持,过程变更成功的几率几乎为零。

  3、忘掉敏捷、忘掉领域驱动、忘掉概念。由于领域驱动设计方法的看似晦涩难懂,容易让组织实践领域驱动的人陷入学院派或教条主义的误区,这表现在:组织者更倾向于使用专家给出的标准术语对领域驱动设计的方法进行解读而缺乏与企业实际相结合的形式。我个人认为,为了更好的推广领域驱动设计的应用过程,不应该局限于教条主义,不要过分关注于概念、框架或自动化的工具,而是把领域驱动设计过程,解释成一种发现需求、解释需求之间的相关性、收集实例、设计测试、以及形成可自解释的开发代码的过程。

  4、从一个小项目和简单项目开始,探索建立一套行之有效的方法。从一个业务结构清晰、容易细分出应用场景和业务活动的项目出发,避免陷入大项目难以控制边界的过程,而且大项目如果没能更好的实施,只会一发不可收拾。有网友说,由于项目需求的极度不确定性,所以他觉得有必要引入领域驱动设计的方法来解决这个问题,我个人认为,这样的做法只会导致项目更加一发不可收拾,尤其是在一个学习能力并不好的组织中开展领域驱动设计实践、且大家都对这套理论一知半解的前提下。

  5,从产品语言中提炼统一语言。axure软件的流行,让通过原型文档这种可视化需求表达成为主流。原型语言与需求的高度贴近,也便于产品研发团队从中形成统一语言。

  6,形成可用的产品术语表。从统一语言出发,形成可以指导编程的术语表,并形成对应的中英文对照表,可以便捷的为开发过程提供变量命名的规则,尤其是许多开发者本身的英语水平就不是特别好,如果形成这样的规则,或许能为代码的开发过程带来许多便利。

640?wx_fmt=png

  7,从统一语言和需求中提炼用例图。按照张逸老师的说法,用例或用户故事应该满足6w特性,可以尝试站在用例的角度思考这样的问题:

  • 到底谁是用户?需要执行这一活动的角色到底是谁?

  • 为什么需要查询功能?

  • 究竟要查询什么样的内容?

  • 为什么需要了解分配给我的任务情况?

  8,从用例图和业务流程中识别限界上下文。没必要一开始就采用四色建模法,采用比较简单的领域场景分析的用例分析方法进行分析,同样是不错的选择,例如从分析业务活动间的语义相关性,也是一种值得尝试的方法。

总结

  人生三境界:看山是山,看水是水;看山不是山,看水不是水;看山还是山,看水还是水。大概技术领域也同样如此。

  回到一个古老的问题,有人问:如何给一个变量命名,词穷了怎么办?专家的回答是,按领域驱动设计的方法对变量进行命名。这就是实践领域驱动设计的大师高论,已经到了看山还是山的地步。而普通开发者们,总是看了几篇领域驱动设计的文章,就会以为嗯,我遇到的这些问题,用领域驱动能解决,然后,就陷入一堆概念之中不可自拔。

  实践是检验真理的唯一标准,唯有真的使用一个项目开始实践,才能真正体会领域驱动设计的精髓。领域驱动设计思想,是一种充满魅力的软件理论方法,然而要把这套理论真的用起来,依然需要经历一个从新手到高级新手,再到胜任者、精通者和专家的学习过程。本文也同样属于一位处于新手村学习者的个人见解,班门弄斧,期待能抛砖引玉,措辞多有不当,还望海涵。

  参考资料:1、Eric Evans《领域驱动设计·软件核心复杂性应对之道》

          2、张逸 《GitChat讲座:领域驱动设计实战》

         3、Gojko Adzic《实例化需求》

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

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

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

相关文章

H - Great Cells Gym - 101194H(数学推导/思维)

VJ地址 ps:在训练时写这道题 差点被送走了 我们可以发现给出的公式可以转化这样 这个就不说了,就是k^(nm)所以排列的可能; 然后我们要重点观察这个公式,可以发现g * Ag(方案数 * good点的数量) 可以意味这组成一个…

基于Dapper的开源Lambda扩展,且支持分库分表自动生成实体之基础

LnskyDB是基于Dapper的Lambda扩展,支持按时间分库分表,也可以自定义分库分表方法.而且可以T4生成实体类免去手写实体类的烦恼.文档地址: https://liningit.github.io/LnskyDB/开源地址: https://github.com/liningit/LnskyDBnuget地址: https://www.nuget.org/packages/LnskyDB…

技术达人“创造营”官宣:Microsoft Learn 学习平台C位出道

真的大神敢于直面随时更新的IT技术你是要做一个平平无奇的“合格员工”?还是要做一个博古通今的“江湖百晓生”?转型变化,是时代的氛围面对日新月异的技术更新一不留神,就会沦落为“技术支持滞后人员”在微软,有这样一…

P2839 [国家集训队]middle 二分 + 主席树 在值域上建区间

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 我们先解决怎么判断中位数的问题&#xff0c;我们可以二分一个midmidmid&#xff0c;将<mid<mid<mid的值都变成−1-1−1&#xff0c;其他的数都变成111&#xff0c;那么当全部的和…

读再多书都没觉得自己变强?试试我这“5年陈”的方法

这里是Z哥的个人公众号每周五早8点 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「76」篇原创敬上4800字巨献奉上hi&#xff0c;大家好。三周过去了&#xff0c;上次教你的几个「速读」技巧练习的怎么样了&#xff1f;上周&#xff0c;已经有不少小伙们开始催…

Educational Codeforces Round 77 (Rated for Div. 2) C. Infinite Fence 数论

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 碰到这样的题肯定是先写几个找找规律了&#xff0c;随便写几个就可以发现是以lcm(a,b)lcm(a,b)lcm(a,b)为一个循环&#xff0c;所以我们只需要在一个周期lcm(a,b)lcm(a,b)lcm(a,b)中求最长…

C# 内存的理解 通俗说

一.概念堆栈是什么&#xff1f;在说堆栈之前&#xff0c;先说说内存是神马&#xff1f;内存&#xff1a;程序在运行的过程&#xff0c;电脑需要不断通过CPU进行计算&#xff0c;这个计算的过程会读取并产生运算的数据&#xff0c;这些数据需要一个存储容器存放。这个容器&#…

P3899 [湖南集训]谈笑风生 主席树解决二维数点

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 由于a,ba,ba,b都比ccc厉害&#xff0c;那么a,ba,ba,b一定是某个是某个的祖先。那么就分为两种情况了&#xff1a; (1)(1)(1) bbb在aaa上面&#xff0c;约定depth[1]1depth[1]1depth[1]1&am…

打造 .NET Core 链接转发服务

我最近使用 .NET Core 2.2 造了个名为"Link Forwarder" &#xff08;链接转发器&#xff09;的 URL 转发服务&#xff0c;并已开源。目前预览版已部署到我的子域"go.edi.wang"。本文将分享我如何构建这个项目&#xff0c;以及我学到的东西。为了帮助大家了…

P3293 [SCOI2016]美味 主席树 + 伪01trie

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 看到异或的话&#xff0c;很容易想到用01trie来贪心的搞&#xff0c;但是这个题涉及区间问题&#xff0c;直接搞的话需要将[l,r][l,r][l,r]的数都插入trie里面&#xff0c;这样的复杂度显然…

Abp 0.18.0 正式发布! -ABP CLI,新模板和其他功能

ABP CLI, v0.18版本新模板和其他功能ABP v0.18已发布, 包含解决的80个issue, 550次提交.网站更改abp.io网站完全更新以突出ABP框架的目标和重要功能.文档和博客网址也会更改&#xff1a;abp.io/documents移至docs.abp.io.abp.io/blog转移到blog.abp.io.ABP CLIABP CLI(命令行界…

短信验证码“最佳实践”

1、背景年初&#xff0c;从外地转移阵地到西安&#xff0c;转眼已两个多月。很久不写业务代码了&#xff0c;到了新公司&#xff0c;条件恶劣到前所未有&#xff0c;从需求&#xff0c;设计&#xff0c;架构&#xff0c;实现&#xff0c;实施&#xff0c;测试&#xff0c;bug修…

Insider Dev Tour 2019巡演中国站

Insider Dev Tour 2019全球巡演中国站落下帷幕&#xff0c;在线直播加六大城市会场&#xff0c;作为四十余位讲师的一份子&#xff0c;我在线分享了Microsoft Graph及Microsoft Teams开发平台的内容&#xff0c;很高兴与几千位开发者共同度过了一个特别的星期天&#xff0c;很不…

HDU - 6267 (概论/找规律/递推)

VJ地址 题目大意&#xff1a; 有n个节点 从0-&#xff08;n-1&#xff09;&#xff0c;连边的规律为 即i点的父亲只能是比i小的数&#xff0c;而且是随机的&#xff0c;现在随机选择应该一个节点作为根&#xff0c;求这子树的和的期望是多少。 思路&#xff1a;可以知道总共有…

Microsoft Graph Toolkit 初探

在今年的Build大会上面, Microsoft Graph 产品组公开宣布了一套新的Web组件&#xff0c;Microsoft Graph Toolkit&#xff08;简称mgt&#xff09;&#xff0c;这套组件可以与任何前端开发平台无缝整合&#xff0c;通过几行代码就能实现基于Microsoft Graph的应用&#xff0c;而…

终于等到你!微软正式上线 Windows Terminal 预览版

前一段时间&#xff0c;一直在知乎、技术社区收到技术小伙伴们的终极拷问&#xff1a;微软Build 大会上提到的「6月中旬」要上Windows store 的 Windows Terminal 到底啥时候可以用到呀&#xff1f;有一次&#xff0c;我跑去我给 Windows Terminal 提的某个 issue 里问 Windows…

牛客练习赛76 E 牛牛数数(线性基加二分)

牛客地址 思路&#xff1a;全部组合异或&#xff0c;很容易想到使用线性基&#xff0c;正好线性基中有一个求第k小的用法&#xff0c;那我们可以二分来找 K是第几小的数&#xff0c;然后用总数减去。 #include <iostream> #include <cstdio> #include <fstream…

几种设计良好结构以提高.NET性能的方法

写在前面设计良好的系统&#xff0c;除了架构层面的优良设计外&#xff0c;剩下的大部分就在于如何设计良好的代码&#xff0c;.NET提供了很多的类型&#xff0c;这些类型非常灵活&#xff0c;也非常好用&#xff0c;比如List&#xff0c;Dictionary、HashSet、StringBuilder、…

牛客挑战赛47 D Lots of Edges(最短路+递归枚举子集)

牛客挑战赛47 D Lots of Edges 思路&#xff1a;点的权值最多只有&#xff08;1<<17&#xff09;-1(131071) ,那我们可以枚举终点的值来算最短路&#xff0c;每个点能连边的值都是固定的&#xff0c;可以通过递归枚举子集&#xff08;技巧&#xff09;来找&#xff0c;每…

.NET CORE下最快比较两个文件内容是否相同的方法

最近项目有个需求,需要比较两个任意大小文件的内容是否相同,要求如下:项目是.NET CORE,所以使用C#进行编写比较方法文件大小任意,所以不能将文件内容全部读入到内存中进行比较(更专业点说,需要使用非缓存的比较方式)不依赖第三方库越快越好为了选出最优的解决方案,我搭建了一个…