为什么业务层这么薄三层架构流行起来之后我们很清楚的知道UI层负责页面交互并调用下一层也知道DAL层就是和数据库打交道。但BLL层什么才算是“业务逻辑”有各种各样的解释但这些不都是sql做的么对于绝大多数的应用系统而言除了对数据库进行“增删改查”以外实在不知道还能做些什么更何况不是还有超级强大的存储过程么所以很多系统即使勉强弄出一个业务层也“薄”得不像话像一层塑料薄膜一样让人有一种把它立即撕掉的强烈的冲动。为什么会是这样呢这得从.NET阵营从历史说起。.NET阵营的同学知道三层架构多半是从PetShop开始这被奉为三层架构的经典很多项目甚至是直接复制其架构。在当时它是一种了不起的进步。那时候还是从ASP向ASP.NET转型的过程很多asp项目sql代码都还是写在html里面的所以UI和DAL的分离无疑具有明细的示范效应。但微软的步子不大不小刚好扯着蛋。步子小一点做成两层架构估计一点问题都没有大家都能接受步子再大一点就得上ORM可惜微软当时还没条件支持。所以就搞出了这么个不明不白稀里糊涂的概念出来折磨了我好久好久……长期以来.NET的阵营在应用级层面其实是“面向数据库”的。从DataSet、DataGrid、DataSourceBinder之类的都可以看出来。即使是Entity Framework最开始也是从数据库的表向.NET的类进行映射。这些都极大的制约了.NET阵营同学面向对象的思维拓展。好在我终于跳出来了。面向数据库为了说明我们举一个最简单的例子。需求是记录文章Article的浏览数ViewCount。每当文章被阅读View一次浏览数加一。看到这个需求你首先想到的是什么是不是1UpdateArticlesetViewCount ViewCount 1;如果是这样的话恭喜你你还牢牢的守住了“面向数据库”的阵地。123456/*面向数据库并不是不可接受的面向对象也并不一定比面向数据库“高级”。这只是两条道路的选择如果你愿意看一看另外一条路的风景就请继续否则就此打住吧。*/面向对象那么面向对象或者领域驱动应该是怎么做的呢1234567891011publicvoidView(){//从数据库中取出ArticleArticle article session.LoadArticle(articleId);//改变Article的ViewCount属性article.ViewCount 1;//将改变后的Article再存入数据库session.Save(article);}有什么感觉眼前一亮还是不可思议想得更深一点的是不是觉得这是多此一举一句sql就能解决的问题搞得这么复杂我当年考虑最多的最不能接受的是性能问题。这必须利用ORM即使不考虑ORM生成的sql高不高效就这生成sql的开销应该就不低吧这样做取数据打开一次数据库连接存数据又打开一次数据库连接。就算有连接池但能省一点就省一点不是更好所以如果你也和我一样倒回去看我之前的博客吧这样做还有其他很多具体的技术问题我们后续博客会逐一展开说明。为什么我们还是回到大方向上来为什么要这么做换言之“面向数据库”有什么问题或者说“面向对象”有什么好处我觉得“抽象”、“解耦”、“复用”之类的说法都还没有触及根本。最根本的原因还在于我们的大脑我们的大脑不适应于把这个世界抽象成一张一张的表而更适应于一个一个的对象。随着系统日趋复杂这种现象就表现得越明显。我曾经参与过一个项目它的数据库结构打印出来得用地图那么大一张纸我不知道算A几了密密麻麻的全是表各种线条交错其中我看着就头皮发麻。部门里面像个宝贝一样把这张表供着因为公司没法打印也没法复印啊我不知道他们最开始是怎么得来的估计肯定麻烦如果你一边读一边在想就会发现“不对呀有多少表就有多少类类图不是一样复杂吗”是的而且由于抽象类很可能比表还要多。但是有于抽象在我们进行架构、设计、沟通的时候可以暂时的抛弃很多细节。比如我们可以说“文章被评论之后文章作者的积分加10分”这个时候我们就不考虑文章有很多种博客、新闻、问答、评论……也不考虑积分增加是直接改积分总分呢还是添加一条积分记录或者还要同步……。如果只有表你怎么说当然表的结构也可以设计成类似于继承的样子类的继承关系也最终会映射成表结构但是在交流沟通中你如何表明这种抽象关系呢单纯从程序的角度上说使用ORM面向对象还增加了系统的复杂性。毕竟多了一道工作而且把对象映射到数据库不是一件简单的工作尤其是你还要考虑性能问题的时候。那为什么我们还要这样做委托换言之把复杂性往其他地方推。我记得我反复讲过这一点架构的一个重要工作就是把复杂性进行拆分和推诿。拆分估计大家好理解但“推诿”是个什么意思推给谁呢管它呢我只做我分类的事其他的UI推给BLLBLL推给DALDAL推给DBADBA推给采购部……写在这里很搞笑但事实就是这样的。在性能篇我说你要写高性能的代码你就是抢了人家的饭碗就这个意思。UI都把DBA的活儿干了人家吃什么你代码都写成01001010101010二进制了别说做汇编的估计做CPU的都活不下去了。我们这里就是把复杂度推给了Map团队、ORM工具开发商和DBA。因为我们要和客户谈需求啊典型的是领域驱动要和客户/领域专家找到“共同的语言”这共同的语言是什么是表结构估计如果开发的是一个财务会计系统这还是可行的——估计早期的系统大多就是财务报表类系统说不定还真是这样。为什么面向对象从Java开始流行Java是虚拟机可以用在微波炉报警器之类上面的底层数据结构可以完全脱离数据库啊.NET做什么起家的就报表啊呵呵。总之发展到今天随着系统复杂性的增加。在系统的架构设计中我们不得不将现实世界首先映射成一个一个可以封装、具有继承多态特性的对象并且将重心放在这些对象关系功能的维护上。数据库就先不管它吧。只有脱离了数据库的束缚我们才能自由的翱翔在面向对象的世界里忘不掉“问题是我忘不掉啊”“我只要看到需求脑子里马上就是数据库就是表。”“没有数据库我都不知道怎么开始写代码了。”……是的忘掉数据库是很难很难——尤其是对于我们这些老人来说。已经浸淫sql数十年的高手你让我忘掉它你以为写小说啊张无忌学太极啊我只能说说我是怎么做到的希望能给你一些参考。我就假设我的系统不是用“关系数据库”存储数据不是mysql不是oracle我用nosql我用xml文件存储行不行nosql怎么用不知道啊我十窍通了九窍。但我就要在我还不知道nosql怎么用的时候就开始构建我的BLL/领域层。而且我只设定几个最简单的假设