关于分层结构的感悟,请指教(转)

 

众所周知,经典的三层结构包括数据访问层、业务逻辑层和表示层。当然,如果继续扩展下去,还可以分为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项目中,因为效率的原因,很多时候要在客户端做一些必填项的验证(其实这也是业务逻辑的一部分),但这是值得的。

   知其然,还要知其所以然,分层是有好处的,程序的结构很清晰,便于除错、便于扩展、也便于阅读。

 

时间: 2024-09-24 20:02:52

关于分层结构的感悟,请指教(转)的相关文章

char-这个结构体占据多少字节呢 请指教

问题描述 这个结构体占据多少字节呢 请指教 typedef struct _person{ char firstname;char lastname;char * title;unsigned int age;char sex;struct spring ls; }Person;这个结构体占据多少字节 解决方案 不是简单相加就好了的,要考虑对齐问题,所以与spring结构关系很大,我用你的这个结构做了一点小实验,结果会根据spring中内置变量的不同而有挺大变化的哦http://blog.csd

我的软件工程硕士论文题目是基于mvc的erp仓库子系统,论文结构请指教!

问题描述 我的软件工程硕士论文题目是基于mvc的erp仓库子系统,今年年底毕业,论文结构请指教!我软件是用c#,.net编的!用的是sql2000,vs2005但我总觉得不是mvc架构,牛人请指教!还有论文的架构我还没想好,请指教! 解决方案 解决方案二:mvc你只要有view,model,controller就算是了,虽然不好用.解决方案三:那c#里面会有view,model,controller三层吗?解决方案四:不会,不过你可以把asp.net看成是v和c,m你自己实现

一个sql的问题,请指教。

问题描述 有5张表,分别是登陆记录表,签到记录表,用户积分表,下载记录表,抽奖记录表,这五张表里面都有一个字段-phone,如果用户执行操作登陆.签到.下载动作.执行抽奖,分别会在这四张表里插入一条数据(四个单独的动作),其中用户积分表里面的结构就是用户id,现在积分,两个字段,我如何写一个sql,能查出这种格式的数据,请指教.  电话     登陆次数     签到次数    积分数量    下载次数  抽奖次数135*       5                   5        

js 对象引用:请指教对象直接量中引用this的问题

如下代码: (1)   var xx = function() {  this.a = "xx";  this.b = this.a;  }  alert(new xx().b);  (2) var x = function() {  this.a = "x";  this.b = {a:"x.b",b:this.a,c:function(){return this.a;}};  }  var s = new x();  alert(s.b.c(

DISCUZNT 程序做的论坛,现在需要在发帖子的时候,把帖子内容传到别的地方,但是 接受到的内容都显示 问号,也不象是乱码,请指教

问题描述 DISCUZNT程序做的论坛,现在需要在发帖子的时候,把帖子内容传到别的地方,但是接受到的内容都显示问号,也不象是乱码,请指教解决了好久想不明白问题,,也经过编码转换处理,但是怎样都是显示问号,有类似问题的朋友请帮忙 解决方案 解决方案二:我会时时关注...请大家帮帮忙解决方案三:显示成问号一定是编码问题..你发送自己定我的东东来测试你的代码..解决方案四:应该是字符集的问题把你的页面改为gb2312或者utf-8试试解决方案五:编码是UTF-8的,,把他转成任何编码,,结果都是???

书籍-想学好android游戏开发请指教

问题描述 想学好android游戏开发请指教 想学好Andriod游戏开发请指教,书籍,或者一些体会等等,各位大师小弟谢过了 解决方案 建议先决定开发游戏的类型(2D游戏.3D游戏...等等)然后选择开发工具(Unity3D.cocos2d.....)选择工具前看一下该工具要求的编程语言(比如Unity3D为以下任意一种:C#.javascript.boo).选择自己语言比较熟悉的开发工具.接下来就是看一下教程做一下小Demo.其他就是看一下手机游戏开发基础比如手机识图大小.drawCall.F

java-运行下面的代码出现图中的错误是为什么?大神请指教

问题描述 运行下面的代码出现图中的错误是为什么?大神请指教 package inheritance; import java.util.Date; import java.util.GregorianCalendar; public class Employee { private String name; private double salary; private Date hireday; public Employee(String n,double s,int year,int mon

wpf c#-有没有办法将异步方法里创建的对象作为数据源关联到控件上...请指教,谢谢

问题描述 有没有办法将异步方法里创建的对象作为数据源关联到控件上...请指教,谢谢 有没有办法将异步方法里创建的对象作为数据源关联到控件上...请指教,谢谢 我将一个异步生成的对象赋给了控件,提示以下异常: "必须在与 DependencyObject 相同的线程上创建 DependencySourc" 根据异常的提示 创建数据源与创建控件不是同一个线程,所以无法作为其数据源,请问有什么方法使得异步里创建的对象能够作为控件的数据源进行绑定.. //异步调用的方法: private vo

ActiveMQ如何实现2个应用通讯之间保持松耦合的关系的,请指教

问题描述 ActiveMQ如何实现2个应用通讯之间保持松耦合的关系的,请指教 ActiveMQ是一个很好的消息中间件,两个应用程序可以在对方系统不启动或者不知道对方网络位置的情况下保持正确的消息传输, 听说有个传输通道,这个传输通道是如何实现的,请高手指教 解决方案 消息队列 没有被处理就一直保存着 解决方案二: 消息队列中的消息是保存在数据库中还是保存在一个文件中?或者说消息队列的本质是什么