域模型向左走(充血),向右走(贫血)

在文章的开始,我先举一个例子
  美国M4谢尔曼坦克 VS德国的虎式坦克(相关资料如下http://mil.eastday.com/m/20070515/u1a2833237.html)

  5:1 在五一期间,电视节目中的二战武器大对决吸引了我,其中当美国大兵说他们在用5辆坦克的代价来换德国人的一辆虎式(I)型坦   克时,我们可以得出一个结论。蒙哥马利和艾森豪威尔是在用二三十人的生命去换德军的一辆坦克(而因为德军坦克装甲厚重,里面的架驶员得以逃生)。这是怎么一种自杀式的进攻呀!也许这么高的伤亡率在最终的胜利面前可能无所谓,但对于士兵([拯救大兵瑞恩])却不完全是这么一回事了。而这里公司的CEO,或高层无疑也可以被视为这两位伟人的化身。为了开发进度和用户,他们可以强迫思维活越的程序员丧失创造力,因为他们需要的是能生成代码的工人(相当于打仗的美国大兵)。而培养这些大兵的军事训练所(软件培训中心)也就成为源源不断制造这种产品的工厂了。
   
  这里不妨把OO域模型比做是虎式坦克,它在代码结构,功能扩展(等同于火力),可维护性,可读性 健壮性安全性(装甲)等方面都是非常有优势的。但同时也出现了问题那就是机动性(太重太耗油,等同于学习成本),以及生产数量(等同于开发速度)成了这个优秀设计思想的制约因素。因为具我了解OO设计会造成开发前期进度上的相对滞后,甚至搭一个框架所用的时间就已经让公司高级无法接受了。而同时一般公司又不愿意为这部分时间成功埋单, 因此程序员就想尽一切办法(甚至生产垃圾代码)来跟上开发进度。虽然有开源框架,代码生成工具等来帮助提升代码的质量和开发速度,但本质上这个项目它已经成了一辆 "谢尔曼坦克",它无法全面享受到OO所能提供的优势,而这里又不得不回头用重构等方法来改善代码质量了。(有些项目甚至连回头的机会都没有)

  最终的结果是美国人说他们的坦克生产出20辆的时候,德军那边只有1辆下线。正是这种数量上的优势最终锁定了美军的在坦克战上的胜局。

  这个例子告诉我们这样一个残酷的事实,好的设计虽然能生产出好的软件,但因为资源(时间,资金,人力等)要求过高。造成了一般企业或公司不想承担。而这时贫血模型这类开发方式乘虚而入,用它们所标谤的优势和开发方式排演着一台又一台的闹剧。

  有些成功是激励,而有些只是兴奋剂甚至是毒药。
  因为今天我在这里所表达的观点会招致相当多的人跳出来与我争论,而不可避免的就是要拿出一堆成功的案例说这里用贫血模型实现的如何如何的好,项目进展如何如何等。
  而我要说的就是当我们为采用贫血域模型而使项目“成功”完成而沾沾自喜时,我们已经在离经叛道的路上越走越远了。
  做为一名程序员,到底是为谁去开发去编程。(A公司,B:为自己,C:为了民族软件产业的振兴D:为了共产主义理想等等。)
   当我们处在利益中心时,左侧是项目经理,技术经理,产品经理为首的公司方代表。 右侧是用户,客户以及其它受众。它们都想为了各自的利益一天到晚的在你身边咆哮,要求你开发或修改这样或那样的代码。表面上我们是项目的主宰,因为如果你没完成工作,项目就不可以完成。但当我们进入设计开发阶段后我们会因为资源的不够使用而不得不做这样或那样式调整和妥协,最终大多数代码都只是一味模式的照搬。这时就谈不上什么将来产品要如何健壮如何好了。因为能对付过眼前摧命的各方势力就已经让我们精疲力尽了。从这方面讲我们已从“主宰”变成了“挨宰”。这时的我们已变成了称铊,要不停的调整自已在称杆上的位置以适应这些催命的人了种种要求。也许不少人这时拾起贫血模型这个稻草,起码它会帮助我们节省设计和开发上的时间,项目最终可能也取得了成功。但当我们过上一段时间再回过头看这些代码,真不知道大家会做何敢想。

  贫血模型(Fat Serviece)服务层成了一个框(此处存在笔误已在回复中修正,敬请谅解!),什么都往进装(越来越臃肿)。本该是域模型中该有的逻辑,这时全被一股脑塞进了Business Logic。当业务逻辑复杂到一定程度时,就会有一些归属不明确的函数或属性出来了。这些不明确的代码相信有相当一部分要放在domain model中会更合理。但因为已经贫血了,所以Business Logic成了它们的避护所。我给这些属性或方法比做“难民”,有些难民可以还活在你的项目中,有些可能在使用一段时间后就死去了(系统不再使用,但未及时清理)。而如果这时公司又找来一个新人去接管这些代码时,乐子可就大了。这就好比让一个后妈去教育一个孩子,如尽心还好(会继续有好的清楚的逻辑)在SERVICE中,而缓和这种矛盾。但多数程序员都不愿做后妈。因此这些方法就会像是没有母亲的孩子一样如游魂野鬼一样在你的项目中游荡。  

  最后,学习成本的降低只能会造出更好与你相同的程序员甚至新人。因为贫血模型没有充血模型那么复杂,实现起来很简单,这就势必造成一个事实,就是一个新入行几个月的人很快也会用这个架构去搞程序开发。这种自贬身价的结果最终可能导致的情况就是当某天工作结束时,你会发现你身边的同时有可能就是一只pig or cow。

  好了,文章写完了,我已经开始准备挨骂了,不过无所谓,希望大家勇跃拍砖!

转载于:https://www.cnblogs.com/yihaha/p/3977614.html

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

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

相关文章

hibernate session 新增、删除,修改、查询样例

1.实体查询 String sqla "from TEST where id? order by sortnum desc"; List list sess.createQuery(sql).setString(0, id).list(); Test test (Test)list.get(0); List list sess.createSQLQuery("select * from TEST where id ?").addEntity(TE…

linux-tar或zip解压缩命令

----------------------------------tar单个文件、文件夹压缩------------------------------------- tar -zcvf /temp/xxx.tar.gz /temp/xxx.txt --压缩 注释:将 /temp/xxx.txt 文件 压缩成 xxx.tar.gz tar -zxvf /temp/xxx.tar.gz -C /temp/ -解压 注释&#…

gwt-ext_GWT,GWT-Ext(SmartGWT),GXT(Ext GWT)常见任务

gwt-ext我正在浏览我们的JCG合作伙伴之一UI-Programming博客上的一些旧文章,并注意到有很多简短的文章,介绍了如何使用GWT,GWT-Ext(SmartGWT)和GXT(Ext GWT)执行一些常见任务。 )。 …

linux服务器之间文件复制命令

scp -r root192.168.1.1:/temp/xx.txt /temp -- 将远程服务器文件拷贝到本地temp文件夹下(secure copy,是加密的),结果:/temp/xx.txt scp -r root192.168.1.1:/temp/ /temp -- 将远程服务器目录下所有文件拷贝到本地temp文件夹下,结果:/temp scp -r ro…

Leetcode: Median of Two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). 2017/2/5更新:如果一定要每次扔一半,使得时间复杂度为O(log(mn))。可以在第一…

Spring 3 RESTful Web服务

Spring 3提供了对RESTful Web服务的支持。 在本教程中,我们将向您展示如何在Spring中实现RESTful Web服务 ,或者如何将现有的Spring服务公开为RESTful Web服务 。 为了使事情变得更有趣,我们将从上一篇关于Spring GWT Hibernate JPA Infinisp…

Whois查询接口文档

Whois查询接口文档 whois(读作“Who is”,非缩写)是用来查询域名的IP以及所有者等信息的传输协议。简单说,whois就是一个用来查询域名是否已经被注册,以及注册域名的详细信息的数据库(如域名所有人、域名注…

DM达梦导入导出整个用户或某几张表

导出整个用户 dexp username/passwd127.0.0.1:5236 FILED:\dataexp.dmp LOGD:\dataexp_20191126.log 导出某几张表 dexp username/passwd127.0.0.1:5236 FILED:\dataexp.dmp tables(tbname1,tbname2) LOGD:\exp_20191126.log 导入 dimp username/passwd127.0.0.1:5236 FILED:…

DM达梦创建表空间用户

使用DBA用户登录创建 --查询表空间物理路径 select * from v$datafile; --创建表空间 CREATE TABLESPACE tablesplacename DATAFILE D:\dmdbms\data\DAMENG\tablesplacename .dbf SIZE 10240; --创建用户 CREATE USER username IDENTIFIED BY usernameusername DEFAULT T…

ruby和python_Ruby,Python和Java中的Web服务

ruby和python今天,我不得不准备一些示例来说明Web服务是可互操作的。 因此,我已经使用Metro使用Java创建了一个简单的Web服务,并在Tomcat上启动了它。 然后尝试使用Python和Ruby消耗它们。 这是全部完成的过程… Java中的Web服务 我从Java中…

USB描述符【整理】

USB描述符 USB描述符信息存储在USB设备中,在枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主机,USB主机分析返回来的数据,判断出该设备是哪一…

io调度maple调度程序_调度Java应用程序中的主体

io调度maple调度程序许多项目需要计划功能,例如我们计划的工作,重复的工作,异步执行等。 我们的首选方法是使用企业作业调度程序,例如OpenSymphony的Quartz。 使用计划任务进行编码时,最棘手的部分之一是执行部分。 这…

java 线程 Thread Runnable 实现样例

1: /** * Thread 实现多线程样例(可继承) */ public class ThreadImplementsTest implements Runnable{ public String params; public ThreadImplementsTest(String params) { this.paramsparams; } Override p…

什么是垃圾回收?

以下是我们的垃圾收集手册中的一个示例,该手册将在接下来的几周内发布。 同时,花点时间熟悉垃圾收集的基础知识-这将是本书的第一章。 乍一看,垃圾收集应该处理顾名思义的问题-查找并丢弃垃圾。 实际上,它所做的恰恰相反。 垃圾收…

Extjs弹窗-简单文本编辑框-Ext.Msg.show

var datavalue测试202109;//文本传入数据 Ext.Msg.show({ title:标题, msg:说明, width:600, height:500, prompt:true, multiline:200, closable:true, …

Extjs tree树的生成

前端代码:先后顺序引入extjs-base.js 和extjs-all.js function initTree(){ var Tree Ext.tree; tree new Tree.TreePanel({ id : treeid,//自定义treeid el : tree_id,//div标签id split : false, monitorResize :true, …

在标记的HREF属性中javascript:alert(this.innerHTML)会怎么样?

在标记的HREF属性中javascript:alert(this.innerHTML)会怎么样? 原文:在标记的HREF属性中javascript:alert(this.innerHTML)会怎么样? <a href"javascript:alert(this.innerHTML)" mce_href"javascript:alert(this.innerHTML)">标签</a> 上面…

Getter DI是个好主意吗?

有时&#xff0c;您可能会听说通过getter方法完成的依赖项注入&#xff0c;该方法会覆盖子类或伪造测试框架。 它允许类具有一组设置的依赖关系&#xff0c;该依赖关系实际上是经过硬编码的&#xff0c;但是可以根据需要“注入”。 从现在开始&#xff0c; 我已经写过关于所谓…

java数组根据下标插入数据

/** * * param arr1 源数组 * param n 下标 0...n * param value 值 * return */ public static String[] insertArray(String[] arr1,int n, String value){ //复制一个长度1的数组 String[] arr2 Arrays.copyO…

Javascript - 栈 和 单链表

最近在重温数据结构&#xff0c;于是写了一些代码玩玩&#xff0c;都是很初级的&#xff0c;表喷各位。。。。 function Stack() {this.dataStore [];this.top 0; }Stack.prototype {length: function () {return this.top;}, push: function (element) {this.dataStore[thi…