为业务逻辑层正名:欢迎大家谈谈如何划分三层架构

lyserver 2012-05-02 02:58:43
加精
关于什么是三层架构,眼下应该算得上是“老少皆知”,在此就不谈了。此贴只想让大家一起讨论一下如何划分三层。我首先抛砖引玉,谈一下自己的看法:
我是从90年代中期从MIS开始、经历了信息管理系统逐步细化、分化发展的过程:ERP、CRM、PDM...。在最早做项目时,一般是C/S的比较多,项目的开发过骤是:需求分析、系统模型、业务流程图、数据字典、系统实现,其中前三个步骤需要反复几次,定版后才开始设计数据库和编写代码,偷懒时会直接用系统模型来代替业务流程图。在系统实现阶段,一般会分离表现和业务,以便后期进行美化。如果是网络版且需要事务,则会在表现层和业务层之间插入一个网络事务处理层(有时用第三方中间件,有时则自己用DCOM或COM+实现)。
那么,这里的业务是什么呢?我认为,不管是MIS也好、ERP也罢,所谓的系统业务就是数据的存储、组织、处理和呈现的动作和过程,当我们把这些过程的实现划分到一个运行单元中时,就形成了现在所谓的业务逻辑层。
然而,现在很多公司(包括我们公司)在划分三层时,所有的数据处理动作和过程都放到了数据访问层里,业务逻辑层只是一个传声筒,这让我百思不得其解。与同事们讨论,他们说我OUT了,此业务层非彼业务层,是用来耦合表现层和数据访问层的,同为保留了扩展性(比如加上WCF等),数据层者是一个系统的灵魂。我听后羞愧不已,但心底里还是不明不白。如何BLL不叫业务逻辑层了,叫个中间层、耦合层什么的,可能就好理解了。
可惜的是,不管我有多少困惑,业务逻辑层依然叫业务逻辑层,只不过是一个没有了业务逻辑处理过程的业务逻辑层而已。
一个软件或一套系统,其核心和生命就是业务逻辑处理,c#大家都会,sql语句谁都可以掌握,javascript更是一个好玩具。但是,为什么同样的数据库、同样的开发环境、同样功能的系统实现,有的用户赞口不绝,有的却抱怨连天?究其原因,我想,其中的关键恐怕在于对业务逻辑的理解和实现的差异造成的。就如同银行的柜台业务处理系统,到现在AS满天、银光遍地的时代,依然还在使用基于cursor库的字符终端界面,也没见多少操作人员抱怨过什么,因为它满足了用户的业务需求而不是审美需求!
所以,BLL绝对不应该成为一个传声筒,DAL绝不应该包罗所有业务过程,绝对不应该!DAL只负责具体与数据库进行交互,面对数据库资源,完成数据操作动作;而BLL则对DAL中的数据操作动作进行有机组织,面向业务处理单元,实现业务处理(数据操作)流程。
因此,我心目中的三层架构应该是这样的:
DAL:DAO->DAFACTORY->SQLHELPER
说明:数据访问层的实现就是ORM+工厂模式
DAO数据访问对象,实现数据库资源动作(CRUD)的抽象化和对象化,面向数据库,可以用代码生成器生成。
DAFACTORY数据访问工厂,是实现DAO中CRUD的具象化的一个工厂。
SQLHELPER,数据访问工厂指象的基于SQL SERVER的一个实例,真正实现DAO的CRUD。
MODEL:数据实体,实现数据库资源结构的抽象化和对象化,业务简单时可作为DTO来使用,面向数据库,可以用代码生成器成。
BLL:BO(业务对象),根据业务的关联关系和处理流程,调用一个或多个DAO类的方法实现系统的业务逻辑,面向业务单元,不可以用代码生成器生成(很可笑的是,现在大多数代码生成器居然也生成了BLL,如果真的管用,那还需要开发人员干嘛)。
比如数据访问层有DAO:daoUser、daoUserFavorite,分别对应数据库中的tblUser、tblUserFavorite两个表,前者存储用户的account、password等信息,后者存储用户的favorite等信息,业务需求包括用户登录验证、用户收藏、用户删除等,此时我们可以创建一个boUser类(即User业务管理单元类),它提供了Check、Favorite、Delete等方法,在Delete业务方法中,还存在两个DAO的级联调用,即if(daoUser.delete()==true)daoUserFavorite.delete();。
UI:该层就不说了。
我的理解不知道是否合理,热情邀请大家交流解惑!
...全文
5701 145 打赏 收藏 转发到动态 举报
写回复
用AI写文章
145 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangtianxing007 2012-09-10
  • 打赏
  • 举报
回复
我想说一句,其实楼主的想法更倾向于java那边的MVC,而不是.NET这边的三层架构。两者看起来比较相像,但是却又不同。两者的共同点就是都拥有model,UI层和数据访问层。不同的地方在于,MVC强调的是控制,.NET强调的是业务逻辑。我个人也倾向于MVC的控制层,既一个方法内部根据单一业务需要调用数据层来进行最终的操作。而业务逻辑则不同,他更强调接口的划分,一类事情在一个类中处理。一个可以看做纯粹的单一职责,一个控制器只针对一个具体业务。一个可以看做纯粹的接口隔离,一组业务逻辑针对几个你认为可以划分在同一组的具体业务。这就是我的理解。 因为一般情况下.NET的model是纯字段,一般不会有对象方法出现在model里,总的来说.net的业务逻辑划分更像几个职责明确的管家,MVC的控制更像流水线工人,各干各的。
rhjyy 2012-06-15
  • 打赏
  • 举报
回复
我来说我一点不成熟的感想,欢迎大家指正,但是如果您是只说错不说原因,那么请免开尊口。
我以为有时候是得咬文嚼字一点,分层的意义,前辈们说的很明白:当系统的某一部分变动时,不会导致其他部分的变动。
很多人说现在我表结构要变了,要加字段了,BLL怎么可能不变,我要说,你表结构变了,要加字段了,这说明什么,说明你系统处理的对象都已经变了,这是一个根本性的变化,是整个系统的变动,不是某一部分的变动,所以你要拿这个说分层是费力不讨好,那只能说是你自个儿把分层神化了,想让它把所有问题都解决了。你说你的系统不可能换数据库,不可能c/s改成b/s什么的,这只能说你的系统可能没有分层的需求(但是实际上经常是目标较小,没有想过往大的做,不往大的做当然不需要设计了),你的系统里就不要用分层了,你不能说别人做分层也是白费劲。
然后说回到表结构要变的问题,我觉得如果一个系统频繁的有需求变更,尤其是涉及业务核心的需求变更,那我想这个需求分析人员多少是要负责任的,很多人只是看别人说需求分析很重要,但是实际上对此并没有什么真正的认识,需求分析人员不是记录员,不是当个传声筒把客户说的转述给系统设计者就可以了,一个真正的需求分析人员在整个开发过程中一定是非常重要的,需要的能力也是很不简单的,他要能快速的理解客户的业务核心,能够跟客户做有效的深入沟通,帮助客户避免遗漏需求。
lyserver 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 141 楼 的回复:]
我说的单类是指一个实体 +操作逻辑函数,不仅仅是基本的CURD,也包括复杂点的操作,而且我的CRUD只查询要的字段,大字段不需要我就不读,只更新我要更新的字段 ,至少运行效率个高很多,简洁明了 ,维护也很方便!PS:小公司全是小项目,大项目没做过,确实不懂大项目,勿喷
[/Quote]
与你的思路很接近,可能也是我没做过大项目的原因吧。
lyserver 2012-05-14
  • 打赏
  • 举报
回复
[Quote=引用 139 楼 的回复:]
严重同意53楼的。很多为了有三层,而做三层的,BLL层就给人感觉是多余。
[/Quote]
我把业务逻辑分为三种,一是人机交互逻辑,二是数据库操作和运算逻辑,三是非数据库运算逻辑,而我由于长期做DBMS,因为习惯把数据库操作和运算逻辑当作系统核心逻辑,这种逻辑我觉得应该可以放在数据层,也可以放在业务层,我倾向于放在业务层(当然不是原生的SQL语句),所以才发贴让大家讨论。
sj6071 2012-05-14
  • 打赏
  • 举报
回复
我说的单类是指一个实体 +操作逻辑函数,不仅仅是基本的CURD,也包括复杂点的操作,而且我的CRUD只查询要的字段,大字段不需要我就不读,只更新我要更新的字段 ,至少运行效率个高很多,简洁明了 ,维护也很方便!PS:小公司全是小项目,大项目没做过,确实不懂大项目,勿喷
sj6071 2012-05-14
  • 打赏
  • 举报
回复
看了不少人。说三层好的,举例都说 从B/S变成C/S 或者改了数据库之类的
业务层不要变,
真的系统这些变化多吗? 桌面程序变成WEB的,没事oracle不用了改成SQLSERVER?
这些改变我成人存在,但是你和下面的情况看看,哪种更普遍?

表结构变化 加一个字段 少一个字段(重要的)
最关键的是很多中小公司(我就是)需求都一直在变,你变的过来吗?
PS :我从满地飞的SQL语句时代 变成单类结构时代 ,我觉得单类结构是比较试用我们小公司的
sen2010 2012-05-10
  • 打赏
  • 举报
回复
严重同意53楼的。很多为了有三层,而做三层的,BLL层就给人感觉是多余。
sen2010 2012-05-09
  • 打赏
  • 举报
回复
[Quote=引用 137 楼 的回复:]
基本上同意LZ的观点。
但我不明白的是,现在很多的所谓业务逻辑层只简单的做一个传声筒,意义何在?
举个例子:一个工资计算系统
里面的逻辑包含了:绩效计算和加班费计算等。
我的理解是,业务逻辑层可以包含这两个功能,如果这两个功能涉及到访问数据库,就可以通过Dao访问,如果不需要,则直接把结果返回给UI;如果绩效计算是一个比较复杂的业务逻辑,也可以把它单独设置一个绩效计算层。至于UI跟DAO之……
[/Quote]
囧,DAL写成DAO了。
sen2010 2012-05-09
  • 打赏
  • 举报
回复
基本上同意LZ的观点。
但我不明白的是,现在很多的所谓业务逻辑层只简单的做一个传声筒,意义何在?
举个例子:一个工资计算系统
里面的逻辑包含了:绩效计算和加班费计算等。
我的理解是,业务逻辑层可以包含这两个功能,如果这两个功能涉及到访问数据库,就可以通过Dao访问,如果不需要,则直接把结果返回给UI;如果绩效计算是一个比较复杂的业务逻辑,也可以把它单独设置一个绩效计算层。至于UI跟DAO之间,我觉得如果单单是查库的话,根本不需要经过BLL层,直接访问就可以了,在BLL层多写一个调用DAO的方法有什么意义?
请指教!
tianyu0728 2012-05-08
  • 打赏
  • 举报
回复
其实可以这样分层
ui层就不说了,展现数据结果,接收用户输入
dao层就是负责查询数据库
领域层,每个领域对象负责自己相关的操作以及属性
还有一个可以叫业务层,可以想象成是针对业务需求的,比如简单的一个登录功能,这里就有一个login的操作,但是具体这个实现可能需要领域层的领域对象来完成,比如用户的领域对象需要去查用户名和密码,日志的领域对象需要去记下登录日志,或者其他的一些操作。这一层只是负责组织领域对象来完成业务需求或者说用户操作的。
其他的一些层就不说了,都有比较现成的工具或框架来帮助实现了。
Jarson 2012-05-07
  • 打赏
  • 举报
回复
个人理解,与其强调如何划分三层,倒不如强调搞明白项目需求,项目业务流程,以及项目所涉及到的对象,有了对象就有了实体层,有了业务流程与实体层就有了业务层,而数据操作层只不过是将实体数据用数据库语句呈现;如果要说区分,至少包括这一点,业务层操作的数据主要是实体,而数据操作层操作的主要对象是SQL;如果站在一个系统的全局角度,明白项目业务流程细节,哪什么要划分几层也就比较清晰。
whdrs 2012-05-07
  • 打赏
  • 举报
回复
可以,貌似说得很有道理
kfy0002 2012-05-07
  • 打赏
  • 举报
回复
[Quote=引用 63 楼 的回复:]
个人理解:
第一层: 数据层一个dll负责返回各种数据集合。
第二层: 业务逻辑一个dll付责处理各种业务的逻辑,满足UI的需要。
第三UI层:只管显示自己的数据,发送用户的操作。

每一层只知道调用,你换数据库那是数据层的事情,你换UI那是UI层的事情。

ps:程序不管分几层,主要的是设计是否对业务有充分的了解,如果了解了业务,分层自然而然也就出来了。
还有就是小的系统还分个鸟……
[/Quote]
为了开发速度更快, 我搞的是微三层, 例如winform中包含这个程序的数据访问, 逻辑控制等, 这样从获取的数据sql语句(commandText or store procedure), 到逻辑管理, 界面设计, 权限控制, 数据保存, 代码实现等等基本上自动产生, 一个程序一般几分钟就搞定了; 之所以选择搞微三层, 因为控制不了的几个项目里面自动插入文件, 不知道以后会不会有麻烦?
SONG_CA 2012-05-06
  • 打赏
  • 举报
回复
我不知道你想表达什么意思?难道我说的不是三层架构?。另外,大牛就是大牛,不服真的不行。我对我公司的那些大牛真的佩服的五体投地。想想这些大牛90年代的时候就把SOA的思想应用到产品当中去了,2007年我接触SOA的时候,对比了一下我们的产品,很为这些大牛没有把这些实际的东西上升到理论而惋惜。


[Quote=引用 127 楼 的回复:]
你的这个只不过是一些设计计模式的应用而已,你的那些大牛也是在最初一步一步重构得到的这个架构也不是一蹴而就的...

引用 49 楼 的回复:

给一个三层架构的例子:
我在国内一家电力自动化应用公司做的时候,公司的产品非常注重分层,让我们这些人得益匪浅,全依仗最初的老板技术大牛叉,看看现在的SOA,老板们在90年代初的时候,就已经在我们的产品中实现了。

产品主要是实时接收各类终端设……
[/Quote]
Demo.XIa 2012-05-06
  • 打赏
  • 举报
回复
<script type="text/javascript">
alimama_pid="mm_28485371_2950790_10049903";
alimama_type="g";
alimama_tks={};
alimama_tks.style_i=1;
alimama_tks.lg_i=1;
alimama_tks.w_i=572;
alimama_tks.h_i=69;
alimama_tks.btn_i=1;
alimama_tks.txt_s="手绘鞋 海贼王";
alimama_tks.hot_i=1;
alimama_tks.hc_c="0065FF";
alimama_tks.cid_i=0;
alimama_tks.c_i=1;
</script>
<script type="text/javascript" src="http://a.alimama.cn/inf.js"></script>
战斗生活 2012-05-05
  • 打赏
  • 举报
回复
感觉说得很乱。。。
dfasri 2012-05-05
  • 打赏
  • 举报
回复
所谓的三层架构, MVC架构等等的, 其实到了实际的操作, 很少可以达到理想的状态的.

数据层的存在, 多半是为了UI方便而提供相应的功能调用, UI需要什么样的数据操作, 中间的业务层就提供什么样的操作. 到头到, 只要UI改了, 显示的内容改了, 业务层也得跟着改, 跟理想中的只要把数据给过去了, 怎样显示就由UI自己做是了. 但实际上, 为了减小访问数据库的次数, 减少网络资源的消耗, 业务层总是给当前的UI量身订造一套功能, 当然这套功能或者会带有一定的通用性, 但大部分却不存在通用性的. 并且由于UI的不断要求, 不断改造, 业务层的提供的功能越来越多, 越来越复杂, 到最终维护困难, 无法修补, 甚至由于业务层要处理过多的客户请求, 包含同步等的操作, 变成不可维护也不是什么怪事.

按不同功能分层, 这个是必须存在的, 但是只追求形式而不考虑实现, 感觉就是多余的, 就像关系数据库的范式, 现实中能够用第三范式的, 也小之又小, 毕竟现实得要考虑速度, 访问量, 还有更多更多的东西, 但知道这些理论毕竟还是件好事. 但知道实际结合理论更更重要.

我自己习惯采用的方式, 是采用所谓的 面向对象 数据库的形式, 虽然现实上不存在这类数据库, 但业务逻辑层, 却是遵守着这个方式设计的. 为每种关系建立一个专用的对象, 然后UI就是操作这个对象来做显示的. 根据关系, 不但修改容易, 定位容易, 也清楚关系, 而且功能由于是面对这个关系会存在什么样的访问形式来制定的功能, 可以避免演变成某个特定的UI定制的功能, 重用性也大.
宇峰科技 2012-05-05
  • 打赏
  • 举报
回复
你的这个只不过是一些设计计模式的应用而已,你的那些大牛也是在最初一步一步重构得到的这个架构也不是一蹴而就的...[Quote=引用 49 楼 的回复:]

给一个三层架构的例子:
我在国内一家电力自动化应用公司做的时候,公司的产品非常注重分层,让我们这些人得益匪浅,全依仗最初的老板技术大牛叉,看看现在的SOA,老板们在90年代初的时候,就已经在我们的产品中实现了。

产品主要是实时接收各类终端设备的数据,然后对数据进行处理、分析,展示分析结果并提供业务执行方案。

DAL:全是以DLL的形式被BLL的模块调用,一类终端设备一个DLL,这些……
[/Quote]
sourcex 2012-05-05
  • 打赏
  • 举报
回复
各人有各人的做法。我也说说我的做法。

UI:主要目的是获取和显示数据。这个层面最主要考虑的问题是用户操作、查看的方便,不对数据作任何处理。有空的话就弄得华丽、炫目一点。比如一个项目管理系统,需要跟踪一个项目的进度,设置了几个关键的时间点,需要展示这些数据。简单的做法就是给出一个列表,把关键时间点列出来就可以,但是更直观的做法显示成时间横轴图(甘特图、横道图)。

BL:主要目的是处理数据,把界面的数据处理成数据库能用的数据,或者是把数据库的数据整理成界面需要的数据。这里面其实就包含了很多业务上的逻辑,比如数据的完整性、规范性检查,数据间的逻辑是否正确等等具体业务的逻辑。比如某个功能需要录地址,格式为:xx省(自治区)xx市xx路(街、大道、村)xxx号xxxx,就需要BL来判断是否符合要求。

DAL:负责管理数据的,至于数据存储的方式,可以是数据库,也可以是某种格式的文件。对于数据库来说,直白点就是拼装SQL语句,执行SQL语句的地方。

用户判断一个系统的好坏,只在UI和BL上判断。说白了就是界面看着舒不舒服,操作是不是简单。在深层次一点就是系统能不能帮助自己做一些业务逻辑上的判断。

不过很可惜,也许你能分出很精彩的x层结构,却不一定能写出合适的BL,特别是那些拿系统规模来说自己多NB的人,通常整不出个靠谱的BL。
worldy 2012-05-05
  • 打赏
  • 举报
回复
用户层:它不知道的数据库的存在,也不知道有哪些数据要表达或操作,也不知道数据的内容是什么,它只懂得在用户需要的时候该如何表达数据,懂的该如何接受用户的输入,并提交给业务层

业务层:获取、处理、提交数据(向数据库,向用户),控制用户的错误,确保业务的完整.

数据层:管好数据。数据库不一定是“数据库”,如果合适,文本文件,或者某个格式化的文件,都可以用作数据库,只要你能合适的驱动。
加载更多回复(108)

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧