众所周知,经典的三层结构包括数据访问层、业务逻辑层和表示层。当然,如果继续扩展下去,还可以分为4层、5层……
我相信很多人都用过,很多人都写过,但是为什么要这么做,我相信一部分人是不能够说清楚的,这不是我猜想的,而是遇见过很多想分层但是分的乱七八糟的层次结构。
数据访问层:
功能描述:处理与数据库之间的交互,不应对数据做任何业务上的加工。捕获数据库交互式出现的异常,抛出或记录下来。
说明:它的作用就是数据访问,如果你没有用其他的类似于ORM的框架,那么这里应该是SQL语句集合地(或者你可以把SQL语句写在存储过程中),业务逻辑层和表示层绝对不能出现SQL语句(包括SQL的关键字,单引号、百分号、LIKE等都不能出现)。那么如何组合动态SQL语句呢?这应该是最大的一个问题。我见过很多系统在业务逻辑层定义相当多的型参,然后在表示层收集参数数据,传入业务逻辑层后拼合SQL语句,最后传入数据访问层执行操作,分层的概念已经完全没有意义了。如何解决这个问题呢?最早的强类型数据集、自定义的业务实体,LINQ,或者ORM都可以解决,当然了,这只是他们的一部分功能(其实,我不太愿意用类似于NHibernate的HQL或LINQ)
数据接口层:
功能描述:提供数据访问层的接口标准、以便于提供多数据库的支持,即数据库的随意迁移。
这里我要提一下数据接口层,我见过有很多项目组在数据访问层的上面加了一个数据接口层,然后数据访问层是各个数据接口层的具体实现,但是在业务逻辑层实例化数据层的时候,仍然是实例化到具体的类对象
IDal_MyClass dalmyclass = new DAL_SQLClass();
我不知道为什么要这么做,除了增加了工作量,其他的一点意义也没有。
那么到底需不需要这么数据接口层呢?我认为在做一个支持多数据库的系统(做产品会多见一些,比如一个CRM系统即可支持SQL Server,也支持Oracle和MySql)时就要用到数据接口层了,当然,单单一个数据接口层完成不了这个任务,你还要为每一种数据库单独做他们自己的数据访问层,并且使用工厂模式以及依赖注入(比如Castle)技术就可以实现多数据库的支持了,你可以在产品安装或者运行时随便进行数据库间的迁移。
业务逻辑层:
功能描述:接受从表示层传过来的数据,做业务上的数据校验,并实现业务流程,最后,把加工后的数据传给数据访问层。
你可以认为在三层之间有两堵墙,三层之间谁也看不见谁,我只做好我的本职工作,其他的事情我不关心。业务逻辑层应该是设计者最关注的地方,也是设计模式应用最广泛的地方,业务逻辑层设计的关键就是尽量的实现松耦合,如果业务逻辑层中的各个类之间都有调用关系,那这就是一个很糟糕的设计。进一步来说,如果把这些松耦合的功能模块的接口作为一种服务的模式(比如Web Service)发布出去,OK,这就是SOA。
业务外观层:
功能描述:把松散的业务逻辑层内的各个细分功能在这里整合,而后作为一个子系统的统一接口发布出去。这也是设计模式的一种。
业务外观层应该是对业务逻辑层的进一步封装。这只有在业务逻辑功能十分繁多但彼此间又有联系的时候才会有用。我刚才说过了,业务逻辑层尽量要实现松耦合,但是各个业务之间肯定是有联系的啊,这种联系起来的工作就要交给业务外观层。要把有联系的几个业务逻辑组合为一个子系统,然后在业务外观层中实现这种联系并发布出去。
我见过很多项目有业务外观层,但业务外观层的方法仅仅是对业务逻辑层一个方法的封装。这样做除了增加工作量,没有任何好处,还不如直接调用业务逻辑层。
表示层:
功能描述:从用户控件中取得数据或者从业务逻辑层取得数据后展现出来,不应对取得的数据做任何加工。
在这层要是出现SQL语句那就更不应该了。在WEB项目中,因为效率的原因,很多时候要在客户端做一些必填项的验证(其实这也是业务逻辑的一部分),但这是值得的。
知其然,还要知其所以然,分层是有好处的,程序的结构很清晰,便于除错、便于扩展、也便于阅读。