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

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

----------------------追忆有关分层的古老往事

         我一直认为,程序员也是艺术家,他们撰写的每一行代码,是献给这大好世界的优美诗篇。不同的人,写的代码也许风格迥异。有的,如春风化雨润物无声,有的,如高山流水,曲高和寡,还有的如旱日春雷,先声夺人。而如果说,代码是诗篇,那么代码的分层艺术绝对是最先映入读者眼帘的序幕了。

         分层,一直以来是一个非常经典的软件工程学问题,提到分层,无论是资深或者新入门的开发者,或多或少都有自己的理解。    

         在8年前,我刚参加工作时,有幸参与了比较多项目的研发和维护过程,这些项目的开发者,大多是比我年长几岁的软件开发者。在他们的开发习惯中,往往会倾向于直接在代码中写入用户界面、数据库访问等支持代码,甚至有相当一部分情况下,会把代码写入到用户界面中,这意味着在用户界面层,往往会写入大量的代码,说不定会超过上万行代码。我觉得可以将这种设计,理解为“单层架构“。

        再后来的项目开始有了一点点改变,这个时候的架构,被成为“三层架构“。在.NET开发史上,三层架构成为一种历史悠久的框架,从十年前开始,一直到今天,依然是.NET开发者最为熟练的技术框架。如图所示,三层架构在客户端和数据库之间增加了一个中间层,将有效的业务规则、数据访问等放在业务层中进行处理。界面层主要使用对数据的绑定渲染,再通过数据层实现数据的提交处理。有的开发者说,三层架构通吃一切项目,似乎所有的项目都可以用三层架构来套用。然而在实际工作中,往往会忽略了业务逻辑层,业务逻辑往往会放在界面层或数据层中,最终导致界面层和数据层充斥着臃肿的代码,令人难以维护。

640?wx_fmt=png

 

    

       MVC架构也是一种非常主流的技术架构,这种架构是一种非常优秀的架构,他将用户界面层通过模型层最早来源于上世纪七十年代,为Smalltalk语言所设计的一种模式,许多基于用户界面的架构也受到了他的启发。MVC架构,通过将逻辑、数据、界面显示分离的形式,实现代码的组织,广泛适用于桌面端或网页程序的开发过程。这种架构的特点是耦合性低、重用度高、生产周期短、部署快。但是同样由于缺乏明确的定义,以及代码过于集中,导致代码腐化问题非常严重。

640?wx_fmt=png

 

    

      MVP架构是从MVC架构中演进出来的典型代表,这种架构通过Presenter来处理逻辑,Model提供数据,View负责显示。当然,他和MVC的区别在于,数据的显示往往是通过Presenter来进行的,所有的界面操作也都是在Presenter中实现,这意味着View层,只是单薄的一层。

640?wx_fmt=png

 

         

    与此同时,开发者们也善于使用存储过程或视图等不同的方式写入复杂的业务逻辑,期待的往往是如果是代码发生变更时,只需对数据库进行修改即可,而无需去修改已经部署在用户端的大量的代码。  使用存储过程、触发器或视图等方式,时至今日,依然是备受关注的一种实现技术,尤其是面向传统产业开发的项目,例如面向制造业的工业控制系统,要进行程序的部署仍然需要非常繁琐的流程,这意味着用户层的部署相对来说不方便,而数据库的变动反而更方便。          

  不同类型的架构或设计的理念迄今仍深刻的影响着开发者的思维模式和工作方法,并最终或多或少的影响着软件工程的实现。          

  从高内聚,低耦合的软件工程学基本原则来说,模块与模块之间的关系,称为耦合,而模块内部的关系称为内聚。而分层的目的,正是为了在满足这个基本原则的前提下,提高代码的可用性和稳定性。过少的分层,意味着代码可读性必然很糟糕,甚至不利于软件的编译分发,而过多的分层,则同样意味着模块的维护将对整体过程代码不便。          

      领域驱动设计认为,如果代码中,与领域相关的内容分散在不同的部分,那么要进行业务和代码的分析将变得难以下手。对用户界面的简单调整都可能意味着代码逻辑的变化,而想要调整业务规则,可能需要开发者们去排查与之相关的所有部分,例如界面层,数据层,甚至是存储过程和视图,这种过程实际上已经没办法建立可用的业务模型,甚至没办法建立测试用例和单元测试的开展,只能靠开发者凭经验去处理不同的情况。为了保证代码的可用性,应当尽可能的分析理清所使用的技术和手段,程序层次设计应当简单明了,易于理解。          

  在复杂系统设计中,分层是一种非常不错的理念,其目的是为了更好的实现关注度分离,使设计的每个部分,既能得到单独的关注,也能维护系统内部复杂的交互关系。领域设计认为,上述提到的几种设计模式,往往是下面四种概念的某种变体。

  •     用户界面层(或者表示层),负责向用户显示信息和解释用户指令。这里的用户,既可以是使用用户界面的人,也可以是另外一个计算机系统。

  •     应用层:定义软件要完成的任务,并且只会表达领域概念的对象来解决问题。这一层实际上负责的是系统与应用层进行交互的必要渠道。

  •     领域层(或模型层)负责表达业务概念、业务状态信息以及业务规则。尽管技术细节由基础设施层实现,但业务情况状态的反映则需要有领域层进行控制。领域层是业务软件的核心。

  •     基础设施层:为上面各层提供通用的技术能力:为应用层传递消息,为领域层提供持久化机制,为用户界面层绘制屏幕组件等等。基础设施层还能够通过架构框架来支持4个层次减的交互模式。

        在传统项目中,往往不见得会如此鲜明的划分层次,但是在进行模型驱动设计的关键,正是需要将领域层从复杂的业务代码中抽离出来。在设计过程中,应当采取以下操作:

    1、给复杂的应用层次划分层次;

    2、对每个层次进行独立的设计,使其具有内聚性并且只依赖于它的下层;

    3、采用标准的架构模式,只与上层进行松散的耦合。

    4、将所有与领域模型有关的代码放在一个层中,并让它与用户界面层、应用层和基础设施层的代码分开。

    5、领域对象应当把重点放在如何表达领域模型上,而不需要考虑自己的显示和存储问题,也无需管理应用任务等内容。

    6、模型设计的目的是达到含义丰富、结构清晰、业务鲜明。

       适当的分层,往往会通过架构框架的形式予以体现。在项目开发过程中,我们通常会使用一些框架,这些框架往往来源于平时项目的积累或者互联网大佬的知识分享。但是这些框架往往不见得完全符合我们的项目需求。领域驱动设计认为,好的架构框架既能解决复杂技术问题,也能让领域开发者集中精力去表达模型,而无需考虑其他问题。然而使用框架很容易为项目制造障碍,最终同样会给人造成错误的理解,即,我们这个项目很简单,并不需要复杂的框架。然而,笔者认为,大部分情形所认为的不需框架的原因,往往是项目确实非常简单,或者开发者低估了项目的复杂度,或者由于公司短视的观点,而忽略了代码的架构设计和分层与建模工作,这最终导致项目容易陷入泥潭。

  当然,也同样要克制欲望,贸然选择难以驾驭的框架,反而让项目开发过程变得不可收拾。因此,要选择性的运用框架来解决问题,明智和审慎的应用框架的价值,让开发者专注于核心业务问题的建模工作,才是提高开发效率和程序质量的手段。

相关文章:

  • 领域驱动设计,让程序员心中有码

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

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

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

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

640?wx_fmt=jpeg

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

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

相关文章

YBTOJ洛谷P4551:最长异或路径(trie树)

洛谷传送门 文章目录题目描述解析代码题目描述 解析 本题关键就在于一点: 若把每个点的深度dep[i]定义为从根到节点边权的异或和 那么i到j的路径异或和可以表示为: dep[i] ^ dep[j] 首先要是i、j在不同子树上显然成立 如果他们在同一子树上,…

基于Asp.Net Core打造轻量级内部服务治理RPC(一)

继之前的《Asp.Net Core Docker 搭建》文章末尾说过的,将陆续编写基于asp.net core 打造一个内部服务治理的rpc框架。不过前端时间较忙,所以搁置了一段时间。闲话不多说,下面就来讲讲为什么需要去做一个该框架,以及想法的来源和设…

YBTOJ:前缀询问(trie树)

文章目录题目描述解析代码题目描述 解析 (没有做出来,这个ans的处理方式其实也不难想…qwq) 考虑把T都作为模板串加入trie树 加入每个模板串自然就是按照i顺序的 所以我们在插入t的时候沿途标记一下 新出现的未标记的i的间隔就是当前的i与上…

DP专练1( [NOIP 2003]加分二叉树 + 太空梯 )

我们先慢慢来加分二叉树题目题解简单讲解前序//中序//后序遍历代码实现太空梯题目题解代码实现加分二叉树 题目 题解 简单讲解前序//中序//后序遍历 其实说白了,这个*序就是根root的遍历顺序 先序就是root–>left–>right 中序就是left–>root–>rig…

YBTOJ:运动积分(trie树)

文章目录题目描述解析代码题目描述 解析 做了巨长时间… 进行了一次刺激的阅读理解竞赛… 感谢whh dalao! 那么让我们分析一下这道题 首先我们考虑单个求x选手的q值 不难发现 i 在第j天和x的大小关系只与a[x]与a[i]二进制下不同的最高位k有关 j的第k位与x相同时&am…

年终总结,我为什么离开舒适区?

当圣诞夜过去,也意味着这一年即将结束,迎来崭新的开始,一年时间既短暂,又漫长,当离开人生的舒适区,将迎来一个又一个的挑战。如果说一个人的优秀,取决于他天赋,以及他为之付出的额外…

NC16886 炮兵阵地

题目: n*m个网格,有平原,有山地,平原可以放部队,部队攻击范围如图(不受地形影响)(H为山地,P为平原) 题解: 确定状态: 因为每个炮可…

DP专练2 (大理石 + [ZJOI 2010]数字计数)

你肯定以为DP专练会有很多题, 但是请考虑一下本仙女的DP码力,一次性能更几个题。。。 来吧,别害怕呀~~ 文章目录大理石题目题解代码实现数字计数题目题解代码实现大理石 题目 林老师是一位大理石收藏家,他在家里收藏了n块各种…

YBTOJ:斐波拉契(矩阵快速幂)

文章目录题目描述题目描述代码题目描述 题目描述 关键在于如何转化为本题的题目。。。 设 y(1-根号5)/2$$ 再令: A(n)xn yn 通过尝试可以发现,A其实就是一个1,3为前两项的斐波拉契数列 则 xnA(n)-yn A的值可以用矩阵快速幂来求 而y是在(-1,…

ABP 框架 数据库底层迁移 Mysql 集群

技术交流,请加QQ群:538327407我的各种github 开源项目和代码:https://github.com/linbin524背景笔者 目前架构的IOT 项目是使用abp 框架作为后台,虽然abp的框架适用于中小型项目框架,但由于架构优美,笔者认为还是可以经…

数论练习1 ( 曹冲养猪 + [POJ 2891]Strange Way to Express Integers + 乘法逆元【带证明】)

虽然作业还没有做完,但是我还是放不下它,对此,我只想说: 今天你对作业爱理不理,明天它就让你补到飞起 DP先放放,我们要雨露均沾练习上手:乘法逆元题目题解代码实现曹冲养猪?(互质的…

开发.NET Core NuGet包并实现CI/CD

实际开发中我们需要对一些公共类库进行开发,并基于Jenkins进行CI/CD(CI:持续集成,CD:持续部署),其他项目通过NuGet引用。上文讲述了如何搭建本地NuGet服务器并发布NuGet包,这里不再赘述。CI/CD流程如下图:首…

acwing221 龙哥的问题

acwing221 龙哥的问题 文章目录题目&#xff1a;题解&#xff1a;代码&#xff1a;题目&#xff1a; 题解&#xff1a; 代码&#xff1a; #include <bits/stdc.h> using namespace std; typedef long long ll;int phi(int x) {int ansx;for(int i2;(ll)i*i<x;i)if(x%…

DP专练3:征途

虽然只有1道题&#xff0c;但是含金量还是够够di 文章目录题目题解代码实现题目 题解 我们直接对答案输出格式进行处理&#xff1a;设第 iii 天走的路程为 aia_iai​&#xff0c;总路程为 S∑i1nleniS\sum_{i1}^nlen_iS∑i1n​leni​&#xff0c;那么 v∑i1m(ai−Sm)2mv∑_{i1…

云时代的.NET

编程语言从最初的0101机器码到汇编语言再到面向对象的编程&#xff0c;不断的发展&#xff0c;整个发展趋势呈现高内聚、低耦合、可重用、可理解的特点。最早编程是用机器码&#xff0c;人的大脑不像电脑&#xff0c;无法处理0101&#xff1b;后来汇编语言还是太费解&#xff0…

研究性学习:APP的隐私问题

文章目录写在前面背景&#xff08;problem&#xff09;一个实例(example)手机App用户输入隐私数据的识别与检测技术研究&#xff08;solution&#xff1f;&#xff09;&#xff08;官方&#xff09;概览背景介绍4.系统设计隐私政策引言1.收集信息2. 信息使用3. 信息披露4. 信息…

DP专练4:[SCOI 2010]股票交易(单调队列优化dp)

昨天晚上&#xff0c;初见它时&#xff0c;月黑风高&#xff0c;一个电脑&#xff0c;一支笔&#xff0c;一个人 今天秋高气爽&#xff0c;再一瞥&#xff0c;回眸间 我又来了&#xff0c;honey题目题解代码实现题目 题解 首先这种 iii 天与前面 jjj 天有关联&#xff0c;而…

【做题记录】[NOIP2016 普及组] 魔法阵

P2119 魔法阵 2016年普及组T4 题意&#xff1a; 给定一系列元素 \(\{X_i\}\) &#xff0c;求满足以下不等式的每一个元素作为 \(a,b,c,d\) 的出现次数 。 \[\begin{cases}X_a<X_b<X_c<X_d \\ X_a-X_b2\times (X_d-X_c) \\X_b-X_a<\dfrac{X_c-X_b}{3}\end{cases} \]…

“被狗啃”的按钮引发的开源社区信任危机

昨天&#xff0c;在国外民众还在欢度圣诞期间&#xff0c;开发者社区却对 Antd 开发团队发起了连番的炮轰。一觉醒来&#xff0c;他们发现由自己参与设计的、公司内网、办事系统等网页上&#xff0c;有一些按钮的上面多了一团白色的“积雪”&#xff0c;在白背景下&#xff0c;…

[COCI2017-2018#5] Pictionary(并查集+dfs)

贼ex的一道&#xff0c;卡了本仙女整整7个小时orz 思路容易理解&#xff0c;but码力very重要orz 我愿意花五毛钱提升我的码力&#xff0c;换个脑子也行&#xff0c;不换脸这张脸生得俊俏 luogu传送door 题目 在宇宙一个不为人知的地方&#xff0c;有一个星球&#xff0c;上面…