从桌面到 Web -- 领域模型
让我们暂时告别一下 ASP.NET Core 先介绍一下这个虚拟项目。因为我的主要目的是通过一个项目,全面学习一下 ASP.NET Core,所以这个项目时一个很简单的,不具备实际应用价值的虚拟项目,但是项目会尽可能用到 Web 程序设计的常用技术。
熟悉商品混凝土生产的朋友都知道,在这个领域常用的软件有两种,一个是混凝土生产线的生产控制软件,主要负责监控生产线的运行和按照生产和工艺流程,自动执行生产任务。这个软件一般是厂家自己开发或委托外包开发的。另外一种是生产管理软件,就是混凝土行业中常说的 ERP(名字有点大),一般是专业软件公司提供。ERP(原谅我使用这个名字)根据生产计划生成生产任务在通过接口(大部分是通过一个中间数据库)把任务推送(存储)到生产控制软件(中间数据库),生产任务软件接收(从中间数据库读取)到任务然后自动运行。
混凝土生产上有着多个存储仓,存储各种物料,而生产任务中包含着各种物料使用情况的配方。一个混凝土生产工厂,一般有多条生产线,而为了应对不同的生产工艺要求,不同的生产线有时会存储不同的物料。而ERP 在发送生产任务时,是靠人工来确定某个生产线是够存储需要的物料。这个虚拟项目就是在 ERP 的任务推送节后面增加一套管道机制,通过不同的管道过滤掉不适合的生产线,最后在通过各个生产线的等待生产的任务队列,自动负载平衡,选择最适合的生产线。
这套管道机制应该方便的支持增加和删除管道,达到任务调度的灵活配置。这样我们就可以把新的任务过滤逻辑通过类似中间件的技术添加到整个管道中。
这个虚拟项目的主要是为了学习 ASP.NET Core,索引领域模型设计的尽量简单,但是为了保证项目与实际的尽量贴近,也值得我们好好思考一下领域模型。
说到 领域模型就不得不提到分层架构,站在桌面程序员的视角和Web 方面,分层架构没有大的区别,尤其现在微软在 ASP.NET Core提供大量的技术框架支撑分层架构(MVC,EF Core,依赖注入等)。在这个项目里,我们也毫不例外的使用DDD的三层架构。在表示层,因为这个项目设想中要想管道一样可以快速的接入到搅拌站ERP和生产控制之间,所以表示层被设计为时髦的两个部分组成:管理界面和用于接入的服务API。在数据层,主要提供从另两个方面获取数据源:数据库和其他服务的API ,在部署时要根据ERP和生产控制软件的数据发布方式进行选择和配置,当然选择和配置服务层要用到依赖注入。最后是用于封装业务逻辑的领域模型,业务逻辑是个挺操蛋的词(Martin Fowler 语,至少意思差不多). 使用DDD方式时,领域模型和数据层的映射是个麻烦事,这个留在数据访问层在讨论。
尽管业务逻辑是个很操蛋的词,但是不可否认领域模型作为整个软件和核心价值和灵魂值得我们认真去思考。做个项目的朋友都有体会,如果数据映射(ORM)是个技术问题的话,领域模型的设计更像一个哲学问题。 我们经常会碰到下面的问题:
领域模型设计的不合理,这种软件很难真正嵌入到客户的管理流程或价值链中,用户在使用这种软件是就像骑着阿凡提的毛驴或者开着绝地求生里被打爆轮胎的蹦蹦车一样,虽然有载具了,但是它永远不会按你想要的方向行驶。还有就是个别用户会提出特别各奇葩的业务逻辑。这些奇葩的需求或许会转换成你最不想看到的需求清单。但有时这些奇葩的需求有时确实能提升客户价值链上的某个环节,或者适应客户的某些管理流程。在做项目时还会遇到很多各种各样的问题。大部分业务逻辑问题都指向两个方面,一个是对客户的价值链或管理流程理解不清晰,导致领域模型设计的不合理,第二个是领域模型的扩展性不好,不能对模型进行快速的扩展。他不分第二种情况是第一种的扩展,想想如果客户的管理流程确实支持某种扩展和修改,那我们的领域模型为什么不能支持呢。
作为系统设计人员,我们不应该相信或者说依赖市场部门提供的需求清单。很难想想这些需求清单能够清晰的描述客户的领域模型和价值链。我们常说要找到用户背后真正的需求。如果是企业应用程序,用户本身是企业的价值链和流程的一部分,用户的需求不能脱离企业的价值链和流程,他是需求仅仅是在完成企业流程或实现价值链的同事满足一下自己的价值提升,举个例子说,使用财务管理软件的用户的需求不可能脱离这个企业的财务管理制度,他的个人需求可能是在使用这个软件是能更方便更快,或者是显得他更专业,好向老板证明他的价值。实现个人的需求更过的是靠UI 和门面对象(Fact)的支持,而领域模型更应该真实准确的反应企业的流程和价值链。
在完成一个好用的项目后,项目开发人员几乎都能成为至少半个领域专家,这要得益于他在项目开发过程中不断的和用户交流,再把企业的领域模型应代码重构。企业的流程本身就是一个模型,只不过系统设计人员要通过与用户的交流学习它,在通过自己的语言(UML,编程语言)再把他重构。Eric Evans再《领域驱动设计》中提到过可以通过用UML创建的领域模型和用户交流,我重来没尝试过,不过我坚信,如果你能用 UML 图和用户交流,那么你的领域模型设计的十分成功。
PS:写东西真累,这几年深受焦虑症的困扰,身体一直不好,甚至影响到思维能力和语言表达能力,最近身体好转,想通过坚持写博客慢慢锻炼思维能力和语言表达能力,所以文章的条例和语言有些混乱,请见谅!
PS:原创不易,水平有限,内容漏洞百出,请转发的网站和朋友注明出处。
从桌面到 Web -- 领域模型的更多相关文章
- 从桌面到Web - 领域模型的创建
天佑武汉,天佑中国.这次为全国人民作出巨大牺牲的武汉人是坚强和担当的. 这次疫情期间的自我隔离的一个副作用是第一次享受这个超长假期,本来想好好学习一下Web技术的,但家里的唯一一台计算机被占用,不得已 ...
- 从桌面到 Web - 二十几天学 ASP.NETCore 1
这么多年一直从事桌面开发,一直没有时间好好学学 web 开发.感觉自己就像从石器时代走来的古代类人猿.由于工作的调整,现在终于有时间学习一下 Web 开发.出于对技术和框架的熟悉和继承,决定还是学习 ...
- Fenix – 基于 Node.js 的桌面静态 Web 服务器
Fenix 是一个提供给开发人员使用的简单的桌面静态 Web 服务器,基于 Node.js 开发.您可以同时在上面运行任意数量的项目,特别适合前端开发人员使用. 您可以通过免费的 Node.js 控制 ...
- HTML5桌面通知(Web Notifications)实例解析
先上一段代码,ie不支持,Chrome.fireFox.Opera支持 <!DOCTYPE html> <html> <head> <meta http-eq ...
- J1001.Java原生桌面及Web开发浅谈
自从Java问世以来,在服务端开发方面取得了巨大的发展.但是在桌面/Web开发方面,一直没有得到大的发展.从最初的AWT,到Swing,再到JavaFX,Java从来没有在桌面/Web解决方案中取得重 ...
- 桌面系统集成WEB认证系统方案
最近做的一个项目,有WEB版.WPF版.手机版.领导想集成集团的一个现成的认证系统,姑且称这个认证系统名为 W4认证系统. W4认证系统有如下特点: 1.现成的 2.是个单点登录系统 3.不支持oAu ...
- 浏览器开启桌面通知Web Notification
本文主要描述如何开启各个浏览器的桌面通知功能 一.谷歌浏览器(chrome) 点击地址栏前面的图标
- HTML5开启浏览器桌面通知 Web Notification
说明: 1.Chrome要求必须https才可以开启浏览器通知 2.显示图片在本服务器,不支持跨越 3.自定义声音Chrome不播放,Firefox正常播放 代码如下: <!-- /** * @ ...
- HTML5中的Web Notification桌面通知(右下角提示)
html5桌面通知(Web Notifications)对于需要实现在新消息入线时,有桌面通知效果的情况下非常有用,在此简单介绍一下这个html5的新属性.通过Web Notifications(桌面 ...
随机推荐
- Linux 网络原理及基础设置
临时配置网络(ip,网关,dns)+永久配置 设置IP和掩码 ifconfig eth0 192.168.2.2 netmask 255.255.255.0 设置网关route add default ...
- 防止SyntaxHighlighter.js的闪烁闪一下的方法
SyntaxHighlighter.js是一个代码高亮的JS插件,使用也很简单,但是由于是浏览器段执行JS代码来着色,会出现视觉上闪一下的效果.比如你的20行代码网页打开显示高度为100px,但是Sy ...
- Python--day47--mysql执行计划
1,什么是mysql执行计划? 让mysql预估执行操作:在要执行的语句前面加explain,就不会真的执行sql语句,只是给出了要执行的数据的情况,如大约有多少条,查询类型.
- Python--day26--反射
反射对象的属性:(非常重要) getattr(类名,‘属性名’):获得属性值 使用getattr的好处:需要查看某个属性值的时候,不用再在代码中用if else elif 去判断输入(input函数) ...
- 安装vue-cli和安装nuxt
安装vue-cli:1.npm install vue-cli -g2.vue install webpack 项目名3.cd 项目名4.npm install5.npm i webpack-dev- ...
- Python 科学计算库numpy
Numpy基础数据结构 NumPy数组是一个多维数组对象,称为ndarray.其由两部分组成: 实际的数据 描述这些数据的元数 # 多维数组ndarray import numpy as np ar ...
- UVA 11922 Permutation Transformer —— splay伸展树
题意:根据m条指令改变排列1 2 3 4 … n ,每条指令(a, b)表示取出第a~b个元素,反转后添加到排列尾部 分析:用一个可分裂合并的序列来表示整个序列,截取一段可以用两次分裂一次合并实现,粘 ...
- H3C 单路径网络中环路产生过程(2)
- angular 全局常用指令
1.全局支持 enter快捷键触发事件 // 全局指令 app.directive('ngEnter', ['$window',"$timeout", ($window,$time ...
- H3C 查看设备路由表