前言

  这个系列已经写了三篇,得到了一些朋友的肯定,也收到了一些朋友的反对。在前面的三篇中,我一直至力于编码,很少涉及到理论,因此很多朋友认为我写的东西很肤浅,毫无亮点,或许我的水平真的很有限,辜负了大家的期待。这个系列已经20多天没有更新了,一个是因为时间有点点紧,另一个是因为我现在正在全力的搭建一个案例,然而要搭建起一个能尽量涵盖企业级应用框架方方面面知识的案例并不简单,但是如果没有案例就来写企业级应用框架无异于纸上谈兵。目前我的案例框架尚未完成,还有些东西没有理顺,但是我清楚的知道,我要诠释的是一种怎样编程思想,所以这一篇我想从理论上跟大家理一理,我这个系列到底是要说些什么。

三层架构已经过时了么

  在我的一些评论里面,有人提出了三层架构已经过时了。对于这一点,我是不赞同的,三层架构做为一种经典的软件分层思想,是不存在过时之说的。很多人提出了分三层不够,对于这一点我倒是蛮赞同的,因此,我们在做项目的时候完全可以根据项目的需要在三层架构的思想上面多扩充几层,形成多层架构,但是万事均有代价的,层次愈多,程序的性能也就相对愈差一些,编程起来也就愈繁琐,因为每层次都必须提供相应的实现代码,因此一个好的架构师,应该对项目的具体分层有个合理的掌控。

  三层架构作为一种分层的思想,它并未提供给我们具体的实现。因此一个基于三层架构思想的框架的好坏,与搭建它的架构师的水平息息相关,如果当你看见一个基于三层架构的框架觉得很失望,那么很显然,是这个框架的实现者让您失望了,而并非三层架构的分层思想让你失望了。三层架构做为微软力推的一种软件分层思想,肯定是具有他的存在价值的,而我目前的案例框架也是从三层架构的思想上扩展而来的,其本质还是属于三层架构,只是多分了一个服务层而已,这就好比人家问你MVC是不是asp.net, EF是不是Ado.net,你说不是,那样是会闹笑话的,因为无论是MVC,还是EF都是在后者的基础上做了一些扩张与封装,然后另起一个名字罢了,微软就喜欢做一些这样的事情来唬弄.net程序,把大伙搞的傻傻的,以体现它的高大上.......

我要诠释的三层架构思想

   UI层:这个层我不想多说,因为已经有了一些相应的成熟的技术思想,如果你采用WPF,siverlight技术,那么MVVM编程模式肯定会是你得不二的选择;当然你说你不喜欢这些插件类型的前端技术,你喜欢自己写HTML,CSS,JS,那么很显然微软的MVC框架会让你如鱼得水;你要是实在不会MVC,只会用WebFrom的话,也没关系,尽量采用MVP思想去编写你的代码。 说到这里,我想提醒一下大家,不要把架构与框架等同起来,架构是分层的思想,而框架是具体实现,你们看我们平时耳熟能详的wpf,silverlight,MVC框架,其实也只不过是三层架构里面UI层次的一个实现而已。

    业务逻辑层:很多人对这个层的理解并不深刻,认为只要能够接收到UI层传递过来的请求,一步一步的实现其相关的业务功能(当然期间可能会调用数据访问层,实现持久化)最后把结果返回给UI层,这样的一个层面就是业务逻辑层。当然我承认我并不能说这是错的,目前觉大多数公司的业务逻辑层也是这么设计的,简单粗暴。这种业务组织方式就是大名鼎鼎的事物脚本方式,是一种面向过程的编程方式,程序中每一个业务对应着一个方法,这样的方式对于中小型的项目没啥问题,但是如果项目大了就显得力不从心了,一个方法中可能包含成百上千的代码(当然你说你可以拆开成很多小方法),但是一个实实在在的问题摆在这里,那就是程序中到处是这样的小方法,业务理解起来就特别困难,试想一下当你接手一个项目在理解业务逻辑代码的时候,方法这里跳那里,该有多么悲剧呀。另一个问题这些方法被写出来有多少能够被重用我表示很怀疑。

   基于上面的这些原因,我的案例并不打算采用这种事务脚本的方式,我决定采用面向对象的领域模型来组织我的业务逻辑。说的浅显一点,就是把我们的业务抽象成一个一个的对象(领域模型),当我们要实现某种业务逻辑的时候,我们只需要调用相关的领域模型的即可。当然采用领域驱动编程,远不是一言两语能够说完的,如果细说的话,又可以写一个系列了,本文只是浅浅的点出我的业务逻辑层的组织方式,下面我给出一张截图,虽然里面的代码我并未实现,但是整体的组织思想会是那个样子

    

其中mode文件夹存放的就是我们的领域模型了(业务对象),Repositories这个是数据仓储,在数据访问层我会详细讲到的,services是领域服务,这是因为很可能一些业务涉及到多个领域模型,封装在那个领域模型中,都显得别扭,所以以领域服务的方式提供;而event则是领域模型中的事件了,因为原则上来说领域模型应该是一个纯净的业务实体,不会跟任何的技术相关连,但是有些时候,我们又必须提供一些技术相关的方法,比如在删除一张订单的时候我们要向客户发送邮件通知,这个就涉及到邮件服务了,但是为保证我们领域模型的纯洁,我们采用了事件来隔离的邮箱服务,具体的邮件操作是以事件的方式注入到领域模型中去的,好了业务逻辑层我们就告一个段落.....

   数据访问层:很多人对数据访问层的职责的理解相对狭隘,认为我们的数据访问层只要帮助我们实现增删改查(CRUD)即可,其实数据访问层远非我们想象中那么简单。CRUD是他必须提供的功能,除此之外它还必须帮助业务逻辑层,屏蔽掉具体的数据访问技术的差异,这就要求它提供统一的数据访问接口,如果您读过我前面的三篇文章,相信您对这一方面就不会陌生了。我认为一个优秀的数据访问层,还应该支持工作单元模式,仓储模式,并能够有效的控制并发带来的各种问题,如果您能够不借助ORM框架做到这一点,那么恭喜您,您会是一个很好的微软专家的。就我前面的三篇来说,如果我采用ADO.NET去实现数据访问层,很显然,这将是一个浩大的工程,这就基本上要求我重新写一个类似微软EF的框架了,很显然我不具备这样的实力。下面跟大家着重的说一说工作单元模式,与仓储模式。

   工作单元模式:其实在EF里面已经为我们实现了,当我们做增删改查的时候,我们并不是每次都向数据库提交请求,而是把相应的更改状态记录在内存里面,然后点击提交的时候一次向数据库写入,这样做有什么好处呢?很显然,第一降低了数据库访问次数,提升了性能,第二,所有的操作一次性提交,这样能很好的支持事务操作。工作单元模式说出来很简单,借助EF框架也容易实现。但是试想一下,如果让您亲手去实现这个模式,又该怎么去折腾呢?

   仓储模式:其实这个模式我们经常用到,只是我们没有注意到罢了。比如我们会为数据库每一张表去建立一个数据实体以及操作这个实体的一个专门的数据库访问类,很显然这个数据库访问类就是一个仓存,如我前面几篇文章中的数据访问层中的orderDAL类,但是仓储真这么简单么? 在前面我提到了我们的业务逻辑层将采用领域模型来组织业务。既然是领域模型,那肯定是一个一个抽象的业务对象啦,业务对象里面肯定包含数据与行为。例如订单对应的领域模型中,肯定会包含该订单的所有订单明细实体,他的行为中肯定是包含了对订单明细项的CRUD,那么这个时候,我们的仓储类要解决就是针对我们的订单领域模型的CRUD,很显然这是一个多表操作。我们在仓储中不仅要实现对订单表的CRUD,还要帮助其实现模型中对订单明细的CRUD,或许你认为这个很容易,那么想一想我们如果订单表中还有客户呢?很显然,要实现面向对象的领域模型的数据仓储,并非想象中那么容易,好在EF也提供了相应的支持,如果要自己去写一个ADO.net针对领域模型的仓储,其痛苦可想而知......

   IOC与AOP:显然,我们必须为我们的业务逻辑层屏蔽掉我们数据访问层的技术差异。我们在业务逻辑层统一调用的是数据访问层提供的接口,但是无论什么样的接口都必须提供实例,在我前面的三篇中,我通过读取配置文件,采用反射的方法来提供实例。很显然这不是一种好的方法。我们可以用更简洁的方法,采用IOC容器来帮助我们创建实例,如spring.net,其实目的和我前三篇讲的都一样,就是解除业务逻辑层对数据访问层的依赖。但是我现在想,在我每次调用数据访问层方法的时候做一些数据验证操作以及当我数据持久操作出现问题的时候,我想把异常记录到日志里面。可是我又不想把数据验证与日志写在数据访问层与业务逻辑层的调用方法中,因为每个方法调用都要写的话,无疑代码是冗余的。当然你也可以写个基类来做相应的操作,但是这样做并不优雅。这个时候我们就需要AOP技术了,AOP容器可以让我们在对创建的实例的方法属性等调用之前或者之后做一些逻辑处理,这些逻辑处理是可以很容易在配置文件中注入进去的......

   服务层:这个是我在三层架构的基础上面增加的一个层次。为什么要有这个层次?很简单,我们的业务层被封装成了一个一个的领域模型与领域服务,而我们的具体业务很显然必须调用相关领域模型与领域服务来实现,所以服务层要解决的主要问题就是调用各个领域模型与领域服务来实现我们的业务,要调用领域模型则必须能够创建领域模型的实例,很显然这项工作得交给数据访问层的领域仓储来实现,所以服务层必须添加对数据访问层和业务逻辑层的引用,它将协调整个领域模型与领域服务来完成业务。另外服务层还必须解决一个问题,那就是DTO领域模型的相互转化。我们的数据仓储操作的都是领域模型,而UI层并不关心我们的领域模型,它传过来的数据或者希望得到的展示数据往往很简单,这就要求我们的服务层能灵活的进行DTO与领域模型的转化,有一个第三方框架Automapper在这里推荐一下。

  分布式服务:在我的案例中,我并不打算让UI层直接引用我的服务层,直接调用我们的相关业务。我打算采用WCF分布式技术来暴露我们的服务。这样做好处有两点,第一,UI层彻底的与服务层解耦,第二,当我们的公司,要把项目转化为移动APP,我们甚至不需要修改一丁点的代码,同时我们的业务功能也可以被别的系统灵活的调用,当然这个属于分布式系统的相关知识了。如果细说有可以写一个系列了,目前我们公司的所有业务系统采用了分布式部署,等这个系列完了,我很可能会根据公司项目写一个分布式系统的系列

  总结:本文蜻蜓点水的,粗略的介绍了下我这个系列到底要写些什么东西,虽然不是什么很高深的东西,但是麻雀虽小,五脏俱全,也基本上涵盖了我目前所掌握的企业级应用框架,应该学习与注意的知识点。这个系列,说出来很简单,但是要整合出一个案例,真的很难。二十多天来,我一直埋头写相关的案例,但是发现有很多的东西自己也理不顺。无论如何这个系列我一定会坚持写下去的,希望大家能够支持我,而不是喝倒彩,对大家没一点帮助的或者没一点深度的东西,我也没勇气摆到博客园来。好了已经很晚了,愿园子里面每一个人都能成为大牛。

posted on 2014-07-20 01:42  虔诚者  阅读(5899)  评论(32编辑  收藏  举报