为什么要让我们的“领域模型”裸奔?(上)
我爸是个乡村小学教师对我所从事的软件行业一无所知但是他对我的工作稳定性表示怀疑“你这做软件的要是有一天软件做完了你岂不是要失业了”也许他想起了他作为老师的情况教完一批学生下一批又上来了一茬一茬的。于是又问我“你们是不是一个软件接着一个软件做”我回答他“不是就一个软件好几十个人得做好几年呢。”解释了很多次仍旧没有消除他的疑问“你们做软件怎么会一直做下去怎么没有个做完的时候呢”。如果他在通往张江的地铁上知道有那么多我伤不起的IT同类们他也许会更加迷惑。为什么如此庞大的程序员大军日复一日年复一年地敲着代码生产出无数的软件可是他们不用担心失业为什么需要那么多看上去类似的软件为什么这些软件永远没有做完的那天应用软件独一无二的地方答案其实很简单我们做的每一套软件都是为了解决某个领域的业务需求。而业务需求永远没有停止变化的一天这就是为什么应用软件永远也做不完的原因。我刚开始工作时在一个小团队里为一家公司定制开发ERP其实就是一个中小型的管理系统在知道国内有用友金蝶在做ERP的时候觉得很奇怪有那么好的公司在做ERP我们还有做的必要吗客户怎么不去买用友金蝶呢现在想来这想法很幼稚因为每家公司的业务都是独一无二的因此每个应用软件即使都叫ERP它也是独一无二的。把独一无二的东西分离出去想想我们为了构建一个应用软件起来要做哪些事最基本的三件是Domain Business Logic、PresentationUI展现、Persistence(存数据库)。还有就是AuthenticationAuthorizationCache等等。复杂的系统还包括与其它系统的集成提供ServiceAPI等等。就说最基本的3件吧稍微思考一下就会发现只有Business Logic是独一无二的。Presentation层是个重复重复再重复的事情再怎么不同的应用我们都可以用同一套工具来实现它用Grid来展现多条记录用Combobox来提供选择用MVC模式来分离数据与展现……框架应运而生。Persistence也是个重复重复又重复的事情关系型数据库ORM框架NoSql……同样约定俗成。所有的东西都可以找到框架这就是为什么写应用软件跟写游戏或者写操作系统等比起来是最没有技术含量的。然和唯独“业务逻辑”没有框架。正是这“业务逻辑”让每个应用软件区别于其它应用软件。因此我们决定要做一个应用软件我们要做的就是实现客户的业务逻辑这是唯一真正的目的。持久化UICache……都是手段。如何实现业务逻辑现在知道了我们做的每一个系统都在为客户交付独一无二的业务价值。这就解决了程序员们“存在的意义”的哲学问题。那么如何实现业务逻辑呢把客户的业务需求转化为解决方案的过程就是设计的过程。因此这个问题可以这样问通过何种的设计让客户的业务需求得到满足呢这个问题很傻因为显而易见是通过写代码实现啊这不是常识吗很可惜这不是常识因为很多团队把设计写在设计文档里了。他们把写文档说成设计把写代码说成实现。大错特错代码是唯一的设计MsBuild把代码build成exe才是实现用Unit Test确保自己的设计即代码正确反应了自己脑中的设计意图用Integration Test来确保自己的设计即代码正确地满足客户的需求有着这种认识和追求的程序员是我想要共事的程序员。想起来台湾习惯把程序员说成“设计师”是更贴切的。把代码当做设计的程序员是幸福的比较一下大楼的设计人员当他们设计好的方案设计图纸一旦被建筑工人们开始“实现”的时候他们的设计几乎就不能再改了因为“实现”的成本太昂贵了。而作为软件设计师我们的“建筑工人”MsBuild包工头以及它的团队CPURAM等小兵是多么的廉价和高效几秒钟就把我们的设计给实现了。这就是我们能够利用“重构”技术的理由。想象一下如果大楼设计人员也这么说“你们先按照这方案盖起来我看效果然后再调整重构”……与传统行业的设计师相比我们软件设计师能得到的反馈更快更多因为我们面对的是电脑这就是我们幸福的地方也是我们应该利用的地方。准备写个“软件开发中的反馈系统”系列文章阐述此问题。在哪里实现业务逻辑用代码实现业务逻辑那么在代码的哪个地方呢有很多个地方1前些年很常见如今被人很鄙视的一种是存储过程。这种曾经非常流行的技术自然有它产生的原因。存储过程是什么是数据库里的东西而且是关系型数据库里的东西。很多人的思维是这样的当他试图理解一个业务逻辑时他心里想的是表以及表与表之间的关系这就是Database-Driven逻辑在这种逻辑下把业务逻辑写在存储过程里是很自然的事情。如果把思维切换到Domain-Driven的模式中业务逻辑是我的核心持久化只是一个辅助的手段我可以用关系型数据库也可以用NoSql而NoSql根本没有存储过程如此你把业务逻辑写在存储过程中让人情何以堪啊2写在UI里这就要提到当年的RAD之王Delphi了。并不是说在Delphi里只能这么做而是说Delphi里很多人就这么做UI直接绑定DataSet用户点击了某按钮直接在IDE里双击该按钮生成Btn1_Click方法把业务逻辑通通写在那。这么做有一万种缺点但有一个优点就是RAD中的RRapid。哥用这种方式写过好几年的Delphi不堪回首。3写在MVC的Controller里其实等同于2。现在Asp.net MVC框架很热可是很多人不知道MVC本质上是啥东西。虽然它有个“M”可是他在分层的架构体系里只是非核心的Presentation层的一个pattern而已。跟Domain层毫无关系。4最好的方式当然是写在一个独立的Domain Layer里。别忘了业务逻辑是一个应用系统唯一独一无二的地方。如何实现Domain LayerBusiness Logic Layer我做过几次技术面试一般都会有个问题“你能说说你对架构的理解吗”得到的回答第一句往往是“关于架构一般是分成3层PresentationBusiness LogicPersistence……”。这句话即使是很Junior的人也能说得上来可是再往下问就能问出有意思的东西了3层之间的依赖关系是怎样的一般的回答是Presentation依赖于Business Logic Business Logic依赖于Persistence。可是既然每个应用系统的“业务逻辑”才是应用系统存在的理由才是开发它的目的所在。而UI展现、数据库存储、Cache等都是为了实现“业务逻辑”这个目的所提供的手段都有成熟的框架、模式可用都可以是雷同的。