Spiga

细说业务逻辑(前篇)

2009-10-29 21:51 by T2噬菌体, 7121 visits, 收藏, 编辑

前言

      记得几个月前,在一次北京博客园俱乐部的活动上,最后一个环节是话题自由讨论。就是提几个话题,然后大家各自加入感兴趣的话题小组,进行自由讨论。当时金色海洋同学提出了一个话题——“什么是业务逻辑”。当时我和大家讨论ASP.NET MVC的相关话题去了,就没能加入“业务逻辑”组的讨论,比较遗憾。

      其实,一段时间内,我脑子里对“业务逻辑”的概念也是非常模糊的。但在不断地阅读、思考和实践过程中,这个概念及其相关的内容才在我脑子里渐渐清晰。我想,很多朋友也许也对这个概念不是很了解,所以愿意结合既有资料和自己的思考,总结一篇关于业务逻辑的概述性文章,一则与朋友们分享探讨,二则也是为自己对业务逻辑的学习做一个总结和提升。因为我还不敢说对业务逻辑内涵及外延理解的非常充分,所以文中如有不当之处,还请各位不用客气,尽管批评就好!

内容提要

      ===================前篇=====================

      前言

      内容提要

      1、我把业务逻辑丢了!——找回丢失的业务逻辑

      2、细说业务逻辑

            2.1、业务逻辑到底是什么

            2.2、业务逻辑的组成结构

                  2.2.1、领域实体(Domain Entity)

                  2.2.2、业务规则(Business Rules)

                  2.2.3、完整性约束(Validation)

                  2.2.4、业务流程及工作流(Business Processes and Workflows)

            2.3、业务逻辑层职责相关争议

                  2.3.1、争议一:数据的格式化

                  2.3.2、争议二:数据合法性及完整性验证

                  2.3.3、争议三:CRUD

                  2.3.4、争议四:存储过程

      ===================后篇=====================

       3、业务逻辑的架构模式及实现

            3.1、Transcaton Script

                  3.1.1、概述

                  3.1.2、分析

            3.2、Table Module

                  3.2.1、概述

                  3.2.2、分析

            3.3、Active Record

                  3.3.1、概述

                  3.3.2、分析

            3.4、Domain Model

                  3.4.1、概述

                  3.4.2、分析

            3.5、各种架构模式的比较及选择

      4、结束语

      参考文献

1、我把业务逻辑丢了!——找回丢失的业务逻辑

      相信朋友们基本都是软件开发人员。不论身处什么职位,我们的工作都有一个共同的目标——制作软件产品。而所谓的软件产品,一定是在某个领域内去实现某些业务。如此看来,“业务逻辑”本应和“软件产品”是紧紧绑在一起的,没有业务逻辑,何来软件产品?

      但是,我发现一个奇怪的现象,一说业务逻辑,很多人就无法形成清晰地印象。例如,经典的三层架构:表示层、业务逻辑层和数据访问层,一提到表示层或数据访问层,大家脑子里马上能产生出清晰的概念,但一提到业务逻辑层,就有点模糊了,或者完全不知道其是什么,或者有个模糊的轮廓,但对其具体的职责、结构不是很清楚。真是奇了怪了!我们天天和业务逻辑打交道,搞不清业务逻辑是什么。

      对于这个奇怪的现象,我思前想后,结合自身的教训(我也曾很长时间搞不清业务逻辑),终于弄清楚了其原因——这和我们接触这个概念的途径和认知结构有莫大关系。

      不知道有多少人和我一样,首次接触“业务逻辑”这个概念是从分层架构中的“业务逻辑层”概念开始的,我相信不在少数。事情坏就坏在这里!为了让朋友们直观看清“业务逻辑”的概念是怎么被我们丢掉的,请大家看一个图,这个图展示了很多人对“业务逻辑”的认知过程。

图1-1

图1-1、狭义的认知分解过程

      如图1-1所示,我们先接触了分层架构,然后对每个层产生了初步的认识。其中,由于表示层和数据访问层的代码职责清晰明确,基本能正确认识。但是,由于我们接触的分层架构的Demo大多业务极其简单,又基本是CRUD操作集中型的业务。所以,我们脑子中就产生了疑问:这个所谓的业务逻辑层是干什么的?怎么就简单封装了一下数据访问层的操作?这有存在的必要吗?由于有了这种“先入为主”的误导,使得很多朋友脑中将“业务逻辑”和“业务逻辑层”两个概念混淆了,始终想不明白这东西到底是什么,做什么用的。再加上很多朋友所看的、所做的系统都是CRUD操作集中型的,就形成了“业务逻辑貌似就是对数据访问操作的简单封装”这一片面概念。

      到底这一概念有没有错呢?其实没错,因为在简单的、CRUD操作集中型软件中,业务逻辑基本就是对数据访问简单的封装。但是,无错不代表全面,这是一种狭义的业务逻辑理解,而且是狭义中的狭义。为什么这么说呢?因为我们不但是在“业务逻辑层”这么一个狭义范围内去理解业务逻辑,而且还是CRUD集中型操作这种“非常瘦”的业务逻辑层范围内去理解,所以,可谓是在狭义的基础上的狭义。

      当我们把这么一个“狭义中的狭义业务逻辑”与“业务逻辑”等同起来时,误会、迷茫、困惑、不屑就出现了。这就如同,给你一只温顺的哈巴狗,还是病怏怏的、无精打采的小哈巴狗,而你把这只“病怏怏的小哈巴狗”与“狗”的概念等同起来了。那么你一定就会为有人养狗看家和警察养狗当警犬抓坏人而困惑:这东西这么弱小,我一脚就踩死了,怎么弄用来看家和抓坏人呢?进而可能会产生“狗狗无用论”,“狗狗废品”等观念。当然,在现实中,很少有人只见过小哈巴狗而没见过狼狗等其它狗类,所以,故事中的误会对“狗”一般是不存在的。但在现实中,确实有很多人只见过业务逻辑中的“小哈巴狗”,却没有见过业务逻辑中的“狼狗”、“藏獒”,所以,这种误会在对“业务逻辑”的理解上广泛存在。

      那么,广义的情况究竟是怎么样的?请看下图。

图1-2

图1-2、广义的认知分解过程

      (注意!凡是不特别说明,下文中所有“数据”一词都指需要持久化的数据,而不包括内存中的临时数据。请各位留心。)

      如图1-2所示,广义的认知分解应该是这样的:软件产品都是在某个领域内实现某些特定业务,所以,软件产品天生应该分解为界面交互部分和业务逻辑部分,其中业务逻辑部分是软件产品的核心,它客观存在于软件产品内部,但是无法对使用者产生直观刺激,因此业务逻辑不能与使用者直接交互。而界面交互部分是业务逻辑与使用者进行交流的接口,使用者通过界面交互部分,与业务进行交流,从而使得软件产品发挥其作用。

      而在具体实现系统时,界面交互部分演化成表示层,业务逻辑部分演化成业务逻辑层。所以,可以认为,数据访问层不是软件产品自然演化的直接产物,之所以出现数据访问层,是因为某些产品的业务属于“数据操作集中型”业务,为了实现隔离、复用等目的,架构师从业务逻辑中分离出了频繁使用的数据访问业务,形成了单独的数据访问层。从广义来说,可以认为数据访问隶属于业务逻辑,因为,数据访问操作实际上也是业务逻辑的一部分。

      总结一下几个要点:(这几个要中的业务逻辑均指广义业务逻辑)

      1)软件产品自然的可分为界面交互部分和业务逻辑部分。

      2)从空间结构上看,业务逻辑和数据访问不是并列关系,而是隶属关系——数据访问隶属于业务逻辑。虽然在具体系统实现层面,数据访问层和业务逻辑层是并列存在,但从概念本质层面上分析,两者是隶属关系。

      3)从时间结构上看,应该是先有业务逻辑的概念,才有数据访问的概念。业务逻辑衍生自软件本身,数据访问衍生自业务逻辑。

      4)因为业务逻辑是软件产品自然的一部分,所以拥有业务逻辑是软件产品的必要条件(读者可以试着举出一个不包含业务逻辑的软件)。但是一个软件可以没有数据访问,如“计算器”、“不带存档的小游戏”等。

      利用以上论述要点和认知分解,朋友们可以试试在脑中重新构筑狭义和广义“业务逻辑”的概念。看能不能把我们丢掉的业务逻辑概念找回来。关于业务逻辑更多的细节,将在下文中讨论。

2、细说业务逻辑

2.1、业务逻辑到底是什么

      在第一大节里说了那么多,相信各位基本已经形成“业务逻辑”的概念了。如果我在这里再啰嗦什么,我不嫌累各位也要嫌烦了。所以,这里我仅给出两个定义。

      广义上的义务逻辑——软件本身固有的一种品性,自然存在于软件产品内部,是软件具有的在某个业务领域内的逻辑,是软件的核心和灵魂。软件产品除界面和交互外的一切都可看作是广义业务逻辑。

      狭义上的业务逻辑——等同于分层架构中“业务逻辑层”的职责,是软件中处理与业务相关任务的部分,一般狭义上的业务逻辑不包含数据持久化,而只关注领域内的相关业务。

      对于以上两种定义,希望朋友们不要割裂开来看,而 要辩证统一的去看,这样,才能构建一个完整而辩证统一的“业务逻辑”概念。在下文中,将不再明确区分狭义和广义,“业务逻辑”一词将代表两者的辩证统一体。

2.2、业务逻辑的组成结构

      业务逻辑作为一个高层次概念,其内在结构也是非常丰富的,下面我们深入其里,去探寻一下业务逻辑都是由哪些更底层的部分构成的。

      2.2.1、领域实体(Domain Entity)

      通俗的说,领域实体就是这个领域内有哪些东西。例如,银行业领域内有账户、支票、前台营业员等实体;B2C电子商务领域有商品、订单、交易等实体;魔兽世界游戏的领域内有角色、种族、道具、魔法等实体;高等代数领域有矩阵、行列式等实体。

      领域实体是某个领域内各种对象的抽象,可以用名词表示(可以是具体名词或抽象名词,甚至动名词,只要其具有名词性),构成了整个业务逻辑的骨骼和静态模型。一般每个领域实体有自己的一些属性和行为。顺便说一句,领域实体的存在时OOA&D的基础。

      在具体的软件系统中,领域实体往往会根据架构的不同有不同的映射存在形式。

      其中一种叫做Business Object(BO),即业务对象,某些文献称其为“充血实体类”,这种对象完整抽象了领域内的某个实体,封装了此实体相关属性和行为。在面向对象的设计和架构中,这种实体类很常见。

      另一种叫做Data Transfer Object(DTO),某些文献称其为“贫血实体类”,其特点是仅有属性,不存在行为。这种实体类主要负责整体性传递数据。另外,与BO不同的是,DTO可以不抽象领域实体的全部属性,而只根据需要抽象一部分。例如,某个“User”实体存在很多属性,但如果某个方法仅需要其联系方式,可以设计一个DTO,仅有id,email,address,phone等就够了。在面向过程的设计和架构中,这种实体设计比较常见。

      2.2.2、业务规则(Business Rules)

      业务规则就是某个领域内运作的规则,构成了整个业务逻辑的灵魂和动态模型。业务规则作用于领域实体,领域实体遵从业务规则进行运作。

      如:在银行领域内,“转账时从A账户扣除相应款项,在B账户添加相应款项,并从A账户扣除相应手续费,并通过某些途径通知A和B账户的户主”就是一条规则。需要注意的是,业务规则比较抽象,并不是需求,需求需要具体且无二义性,而业务规则只是抽象的一种描述,例如,通知户主的途径是什么?电子邮件?电话?短信?并没有具体描述,但在规则中有“通知”这一项,因此不能将业务规则等同于需求。

      2.2.3、完整性约束(Validation)

      领域实体和业务规则构建了业务逻辑的主体,但在这主体之上,还存在着一个限制,这就是完整性约束。

      完整性约束是对业务领域中的数据、规则的强制性规定与约束。这种约束是系统正常运转的保证。

      如“账户密码不能为空”,“身份证号必须符合具体格式规定”,“转账流程必须具有原子性,A账户扣钱、B账户存钱、A账户扣除手续费、通知户主四项操作必须要么都做,要么都不做”,都是完整性约束。

      2.2.4、业务流程及工作流(Business Processes and Workflows)

      有了上述三项,业务逻辑还不能正常工作,因为还没有“启动器”和“过程托管器”。设想我们有了各种实体类,它们有各自的属性和行为,也有定义好的业务规则和完整性约束。现在实体类仅仅具有实现业务规则的能力,但它们如何启动并交互协调完成业务规则呢?因此我们需要有东西去触发和协调实体。

      业务流程或工作流是启动及托管协调领域实体完成既定规则的过程。例如,“在线订购”是一个业务流程,它包括“用户登录-选择商品-结算-下订单-付款-确认收货”这一系列流程。各个实体如会员、订单、商品等已经包含了完成在线订购必要的行为,但仍需一个流程,才能真正完成业务。

      具体到程序中,业务流程也许通过一个方法来实现,这个方法负责启动并协调各个实体类,完成一个流程。

2.3、业务逻辑层职责及相关争议

      2.3.1、数据的格式化

      关于数据的格式化应该放在业务层进行还是表示层进行一直存在争议。我个人的意见是这样的:

      业务层送给表示层的数据应该具备以下要求。1)返回的数据应该完成了所有必要的业务处理和业务计算。例如,若返回订单信息让表示层展示,会有个必要的数据——订单总额。这个数据需要首先用各个订单项的单价乘以数量,然后加和。那么,这个数据应该在业务层完成计算直接返回,总之不应让表示层进行任何业务处理和计算操作。2)一次性返回所有需要的数据,避免表示层再一个Action里调用多次业务。打个比方,例如订单中有个“客户姓名”,这个数据不保存在订单表中,而是通过外键关联的,那么,业务层应该将“客户姓名”一并取出返回给表示层。总之,避免表示层在一个Action里多次调用业务层。3)不携带任何格式信息,仅仅是结构良好的纯净数据,如DTO形式。因为,数据如何展示,是表示层的职责,如何在业务层中返回了过多格式信息,就会造成表示层的修改困难。例如,我曾听说过所里承接的一个实际项目,开始是使用B/S,当时他们的业务层返回的数据全都附带了html代码。后来,客户嫌B/S响应不够迅速(可能是客户公司的网络条件不好),要求改成C/S,当时全傻眼了,貌似几乎修改了整个业务层。那个项目相当庞大,7个子系统,投入200人开发了1年多,想想修改的难度吧。

      2.3.2、数据合法性及完整性验证

      一般做系统,都避免不了数据验证。上文曾经提到,完整性约束是业务逻辑的一部分。如此看来,数据验证一般应该放在业务层。但是,实际情况并不尽然。个人认为数据验证的方式,目前没有统一标准,可以根据需要放在表示层或业务层。但是,我个人不提倡在“表示层的服务端”放置过多完整性验证。因为,表示层的职责应该仅仅是接收数据并传递给业务层,不应对数据是否合法负责。过多的数据验证,不但令表示层代码臃肿,而且使得表示层职责变得不明确。

      可以在“表示层的服务端”放置一些简单的验证,如空值验证,两次输入密码是否一致等,但业务关系紧密的验证,最好放在业务层。甚至有些验证只能在业务层验证,如“当前用户名不能与已有用户名重复”,这种验证需要访问持久化数据,需要由业务层完成。

      这里之所以强调“表示层的服务端”,是因为一般在B/S系统中,都会在JavaScript里加入一些基本的数据验证,如空值检查,格式正则匹配等。这主要是为了减轻服务器负担,将大多数显然包含不合法数据的请求拒绝掉,而不发给服务端验证。当然,因为可能会出现JS被屏蔽或黑客恶意攻击行为,所以,所有验证不论JS中是否验证过,服务端(可能是表示层的服务端部分或业务层)一定要再进行验证。

      2.3.3、CRUD

      CRUD,即常说的增删改查操作。关于CRUD是否是业务层的职责,一直也是争议不断。因为目前并没有权威的定义,所以这里我斗胆说一下我对这个问题的看法。还请大家批判性阅读。

      一说到“增删改查”,大家一定会觉得这理所当然是数据访问层的职责。我认为这个理解是对的,但是只对了一半!之所以这么说,是因为“增删改查”有两个层次含义。

      第一个层次,是数据访问层次上的。在这个层次上,“增删改查”只是单纯的数据库操作,“增删改查”可以理解为“插入一条记录,删除一条记录,更新一条记录的信息,获取一条或多条记录”四个操作,其意义和着眼点完全是数据访问层面上的,不带有任何业务成分和业务知觉。这个层面上的CRUD应该属于数据访问层的职责。

      第二个层次,是业务逻辑层次上的。在这个层次上,“增删改查”是业务领域内实体的变化以及一系列相关反应,“增删改查”可以理解为“领域内新增一个业务实体,领域内去掉一个业务实体,领域内一个业务实体更新了信息,得到领域内一个或多个业务实体的信息”。

      两者最大的不同,是业务层面上的增删改查往往不是单纯的增加减少,还包括实体变化后相关的业务流程。下面举个例子:

      “添加一个新的订单”——这是一条典型的“增”操作。在数据访问层面上,它的意义是“在表示订单的数据表里增加一条记录”;而在业务逻辑层面上,它的意义除了“领域内多了一个订单实体”外,还可能包括“根据业务规则判断是否是重复下单,根据金额对下订单客户的等级做相应提升、发送Email和短信通知客户等”。可以看到,业务层面上的“增”可能不仅是简单封装一个简单的插入记录,可能还要去做其他数据访问——提升用户等级,以及做一些非CRUD的业务操作——发送短信通知。

      在许多稍微复杂的系统中,业务往往不仅仅是封装了一条数据访问操作,而是还有很多如计算等业务处理,一个业务操作期间可能要多次使用数据访问操作。退一步说,即使某个业务仅仅封装了一条数据访问操作,其意义和层面也是不同的,在数据访问层面,仅仅是多了一条记录,而业务逻辑层面,是领域内多了一个业务实体。也许其本质上都是往数据库插入一条记录,但人类的抽象思维可以将之在不同层面上区分,这也是人类思维层面的一种抽象能力的表现。例如,我们知道太阳升起不过是地球自转使得从背阴面转到了向阳面,但当人们看日出时,很少有人会说“看!我们从背阴面转到向阳面了!”,我们会说“看!日出!”,这就是同一事物的不同层次表现。

      2.3.4、存储过程

      也许是性能上的诱惑,许多人喜欢在数据库系统中写很复杂的存储过程。这样,许多业务操作就被写到存储过程中去了。我个人建议,除非对性能要求极高,否则最好还是不要用存储过程实现业务。例如,在一般的系统中,某个业务操作可能需要1秒,而是用了存储过程只用0.1秒,看上去存储过程将效率提高了10倍。但对大多数用户来说,1秒和0.1秒的差别并不大,但是这样做的话,业务会变得十分不容易维护。所以,我个人觉得,除非十分必要,还是不要用存储过程实现业务。

Creative Commons License

本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名张洋(包含链接),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

Add your comment

85 条回复

  1. #1楼 Artech      2009-10-29 22:08
    T2噬菌体是园子里写文章最“规范”的人,坐个沙发,支持一下!
     回复 引用 查看   
  2. #2楼 真水无香.chen      2009-10-29 22:09
    非常不错
     回复 引用 查看   
  3. #3楼 不死鸟之魂      2009-10-29 22:22
    从更广义上说,除了纯技术逻辑的东西,其他都是业务逻辑。所谓纯技术逻辑,是指诸如:使用什么方式访问数据库、文件,如何通信(socket、webservice或其他)等。
     回复 引用 查看   
  4. #4楼 jaygor      2009-10-29 22:41
    非常好的文章,期待你的后篇
     回复 引用 查看   
  5. #5楼 阿sam      2009-10-29 22:49
    “添加一个新的订单”——这是一条典型的“增”操作。在数据访问层面上,它的意义是“在表示订单的数据表里增加一条记录”;而在业务逻辑层面上,它的意义除了“领域内多了一个订单实体”外,还可能包括“根据业务规则判断是否是重复下单,根据金额对下订单客户的等级做相应提升、发送Email和短信通知客户等”。可以看到,业务层面上的“增”可能不仅是简单封装一个简单的插入记录,可能还要去做其他数据访问——提升用户等级,以及做一些非CRUD的业务操作——发送短信通知。
    ====================================
    假设业务逻辑是这样的:添加订单--提升等级--发送Email...
    这些业务是顺序执行的,请问一下它们的事务回滚要如何处理呢,比如提升等级失败--那么添加订单也要失败。。
    在分层结构当中,我是把添加订单,提升等级,发送Email的CRUD操作放在数据访问层进行调用的,但是业务逻辑层上面这三个操作又是一起的,这样就很难使用数据库的事务处理了,难道要对这种操作单独做一个数据访问层的方法吗?
    可能说的比较混乱一点,不知道大家能不能看明白。
     回复 引用 查看   
  6. #6楼 吉日嘎拉>不仅权限设计      2009-10-29 22:55
    金色海洋,前几天也说,不懂到底什么是 业务逻辑,
    应该推荐他看看比较好,大家都觉得是好文章的话。

     回复 引用 查看   
  7. #7楼 三桂      2009-10-29 23:13
    认真看玩了,一行一行看下来,深有体会...好文章...收藏起来以后再阅读阅读,谢谢博主..:)
     回复 引用 查看   
  8. #8楼 Ivony...      2009-10-29 23:25
    分享几个思想片段,我还没有把它们整理成型,只用了自然段来分隔我的意识流。


    首先,我想在一开始LZ就把领域局限化了,使得整篇文章都在围绕着某个特定领域,或者说存在CURD三层这样概念的领域的业务逻辑。或许这是问题的出发点(业务逻辑哪里去了?)但业务逻辑的概念却并不应当局限在这样的领域中。

    我想业务逻辑与业务逻辑层这个名词是有紧密的联系的,业务逻辑,是属于领域模型的一部分,而不是整体(甚至于是毫无必要割裂出来的一部分)。那么为什么会割裂出业务逻辑这样的单独的概念呢,这与硬性的三层划分不无关系。或者说三层架构把整个领域模型割裂了,中间的这一部分最重要的,最明显的就是业务逻辑。

    我并不太赞成将三层架构理解为,界面交互和包含数据访问的业务逻辑。这样的划分是典型的表现和实现分离的理念。这也许是三层架构出现的前因(表现和实现分离的理念显然在三层之前),但如果将数据访问并入业务逻辑,那就不如说是表现和实现分离的理念了。

    或者其实我们可以在这个思路上走下去,包含数据访问的业务逻辑层其实就是实现。那么实现是怎么被割裂成数据访问层和业务逻辑层的呢?这样答案就会明朗化。因为在某些应用领域,其实现(或者说业务核心)就是数据,以及数据的规则。譬如说MIS系统,CMS系统,CRM系统,等等等等。

    简单的说,我们能不能把三层架构套到Windows上面去?显然不现实。三层架构只适用于特定的领域,而在这样的领域上,实现的确就是可以割裂成数据和规则。自然,就可以割裂成业务逻辑层和数据访问层了。


    三层是一个很“经典”的架构,我对“经典”打上了引号,因为我希望表达两个意思。一是三层架构的确很成熟,解决了很多领域的问题。二是三层架构的确在现代的、复杂的某些领域应用软件中,并不是很合时宜,设计是一个创造性的工作,而不是生搬硬套。


    说到这里,我注意到我第一自然段说到:“业务逻辑的概念却并不应当局限在这样的领域中”,但我后面的意识流却在这样的领域中打转了。

    这并不是我脑子短路了,而是因为“业务逻辑”这个词的确产生于这样的领域中,是在这种领域中,从领域模型割裂出来的一个部分。

    那么单就业务逻辑来说,其在领域模型中是什么位置呢?是什么样子的呢?或者说,是不是这个问题的提出者“金色海洋”并不是希望弄清楚业务逻辑是什么,而是希望弄清楚业务模型或领域模型是什么呢?
     回复 引用 查看   
  9. #9楼[楼主] EricZhang(T2噬菌体)      2009-10-29 23:27
    @阿sam

    业务层也可以增加事务控制^_^
     回复 引用 查看   
  10. #10楼 hyping      2009-10-29 23:29
    @阿sam
    数据访问层次使用数据库事务,业务逻辑层次的事务控制可以使用长事务控制。
    如果应用程序运行的操作系统和数据库系统都是windows 系统,使用 system.transaction 命名空间下的组件应该还是很方便的。
     回复 引用 查看   
  11. #11楼[楼主] EricZhang(T2噬菌体)      2009-10-29 23:45
    @Ivony...

    你有一句话说到我心坎里了。我要表达的很重要的一个意思就是不要将业务逻辑局限在三层架构中的业务逻辑层了。如你说的,操作系统也有业务逻辑。
     回复 引用 查看   
  12. #12楼 Ivony...      2009-10-30 00:06
    引用EricZhang(T2噬菌体):
    @Ivony...

    你有一句话说到我心坎里了。我要表达的很重要的一个意思就是不要将业务逻辑局限在三层架构中的业务逻辑层了。如你说的,操作系统也有业务逻辑。



    我也看出来你想表达的这个意思了,呵呵。

    我要好好整理我的思维碎片,我现在有一个感觉,其实你所说的业务逻辑(包含数据访问),应该是业务模型。

    我承认我最近有些FQ,主要就是针对名词乱飞非常不满,因为这会造很多沟通和理解的问题。譬如说这个东西到底是“业务模型”还是“业务逻辑”这个名词其实很无关紧要,却又不得不在这上面打转转。

    我现在也在发现我使用的领域模型一词并不适合类似于操作系统这样的软件,我得好好的整理一下我的思维碎片。
     回复 引用 查看   
  13. #13楼 stu_acer      2009-10-30 00:21
    @EricZhang(T2噬菌体)

    关于业务逻辑层增加事务,能给个例子或示例代码吗?
    业务逻辑层增加事务是否比较成熟的编程框架呢?
     回复 引用 查看   
  14. #14楼[楼主] EricZhang(T2噬菌体)      2009-10-30 00:35
    @stu_acer

    在.net平台下,一般用system.transcation,你可以了解一下这个。用起来很方便
     回复 引用 查看   
  15. #15楼 一抹红      2009-10-30 01:10
    好文,期待下文!
     回复 引用 查看   
  16. #16楼 卡通一下      2009-10-30 07:05
    我是这样定义“业务逻辑”的:

    归纳、抽取、整合现实需求中相对独立的操作。
     回复 引用 查看   
  17. #17楼 金色海洋(jyk)      2009-10-30 07:56
    刚看了一半,要上班了,剩下的有空再看。

    感谢lz的详细讲解,解决了我的疑惑,谢谢!


    这么好的文章怎么没有人推荐呢?我是投了推荐票的,大家是不是看入迷了忘记推荐呀!
     回复 引用 查看   
  18. #18楼 Leon Weng      2009-10-30 08:17
    业务逻辑写的很不错,推荐了一把。
     回复 引用 查看   
  19. #19楼 卡通一下      2009-10-30 08:27
    楼主对存储过程的认识过于片面。
     回复 引用 查看   
  20. #20楼 Silenus-G      2009-10-30 08:38
    很详细的讲解。支持一下。
     回复 引用 查看   
  21. #21楼 戏水      2009-10-30 08:46
    引用Artech:T2噬菌体是园子里写文章最“规范”的人,坐个沙发,支持一下!

    没错 , 他在解决“表达自己的思想”的这个需求的时候 考虑到了用户体验。

    有的人写文章 错字连篇, 言语混乱,文章排版一塌糊涂,却不停地叫嚷着“众人皆浊我独清”

    园子里几位 比如 老赵,会军,王涛 等,还有蒋兄您 的文章都是智慧与美貌并重,内容和形式俱佳的上品。 我的感觉 :水平高的排版也美。
     回复 引用 查看   
  22. #22楼 只说文笔[未注册用户]2009-10-30 08:55
    从结构上看象是写书,从写法上看又有点象“口述”。

    一句话,是用心写的。
     回复 引用   
  23. #23楼 Bees[未注册用户]2009-10-30 09:00
    我想问业务逻辑层是对数据层的封装还是表示层所提供的服务封装?

    例如一个页面是用来添加文章的,可能添加文章的同时还要天tag之类的数据库操作,那么是把添加文章和添加tag封装到一起还是分开然后有表示层那边调用?.....?
     回复 引用   
  24. #24楼 oec2003      2009-10-30 09:04
    引用Artech:T2噬菌体是园子里写文章最“规范”的人,坐个沙发,支持一下!


    都是将博客当论文来写了 呵呵
     回复 引用 查看   
  25. #25楼 八一精神      2009-10-30 09:08
    写的很用心。支持一下。
    目前没接触过大项目。对MVC也不是很了解。
    感触不是很深。继续学习!
     回复 引用 查看   
  26. #26楼 戏水      2009-10-30 09:12
    我个人的经验 感觉 最难得是把 业务逻辑和展现逻辑 如何清晰的分离开。
     回复 引用 查看   
  27. #27楼 我也用“狗狗”来说分层[未注册用户]2009-10-30 09:26
    从冰箱取狗食是“数据访问层”;

    分析狗狗该吃什么,如是早餐、午餐、晚餐还是零食是“业务逻辑层”;

    如何食用,如将牛奶放入碗中、狗粮放入盘中、骨头放入盒中是“表示层”。


     回复 引用   
  28. #28楼 GWPBrian      2009-10-30 09:26
    排版的确很规整~顶下
     回复 引用 查看   
  29. #29楼 Piece      2009-10-30 09:30
    T2是圈子的榜样
     回复 引用 查看   
  30. #30楼 King.Kes      2009-10-30 09:31
    业务逻辑在我的理解中被简化成计算与关联的判断两块。

    比如根据订单金额生成结算账单,结算账单的结算金额首先由业务订单的金额汇总出来,然后根据客户级别或者积分或者打折优惠这些计算出一个账单实际结算金额,此为计算。

    所谓关联的判断逻辑,就如楼主所提的,订单是否重复。再扩展一点,比如一个订单下进来了,先去检查库存是否足够,若不足则提示后台工作人员需要进行进货流程,又涉及到向供应商下单采购,向供应商结算货款等一系列动作,这是我所理解的关联判断。或许有人说应该在下单前就检测库存,不足的就不允许下单或采取其他措施,这个就更加业务逻辑了,这是管理经营层需要决策的事情,技术是为业务服务的。

    比较粗浅,见笑了
     回复 引用 查看   
  31. #31楼 业务逻辑不是“条件”[未注册用户]2009-10-30 09:42
    引用King.Kes:
    业务逻辑在我的理解中被简化成计算与关联的判断两块。

    比如根据订单金额生成结算账单,结算账单的结算金额首先由业务订单的金额汇总出来,然后根据客户级别或者积分或者打折优惠这些计算出一个账单实际结算金额,此为计算。

    所谓关联的判断逻辑,就如楼主所提的,订单是否重复。再扩展一点,比如一个订单下进来了,先去检查库存是否足够,若不足则提示后台工作人员需要进行进货流程,又涉及到向供应商下单采购,向供应商结算货款等一系列动作,这是我所理解的关联判断。或许有人说应该在下单前就检测库存,不足的就不允许下单或采取其他措施,这个就更加业务逻辑了,这是管理经营层需要决策的事情,技术是为业务服务的。

    比较粗浅,见笑了

     回复 引用   
  32. #32楼 金色海洋(jyk)      2009-10-30 09:54
    @Ivony...
    我是希望弄清楚业务逻辑是什么,同时也想知道业务模型或领域模型是什么?

    或者说他们的区别是什么。

     回复 引用 查看   
  33. #33楼 卡通一下      2009-10-30 10:05
    一个“业务逻辑”的实例。

    在医院的HIS系统中,医生工作站、护士工作站、药房工作站、药库工作站等等,都要用到“药品账页”,并对其进行检索。我们把这个共同的需求抽象出来,就是一个“业务逻辑”,将它写成一个通用的模块,供大家使用。

    归纳、抽取、整合现实需求中相对独立的操作。
     回复 引用 查看   
  34. #34楼 Otis's Technology Space      2009-10-30 10:21
    受益很多,感谢了!
     回复 引用 查看   
  35. #35楼 codemonkey      2009-10-30 10:27
    引用EricZhang(T2噬菌体):
    @stu_acer

    在.net平台下,一般用system.transcation,你可以了解一下这个。用起来很方便



    system.transcation使用起来方便 但是部署起来很不方便, 对数据库服务器和web服务器有苛刻的要求。

    我想知道在不用system.transcation的情况下 有什么好的方法实现业务层的事务?
    我现在的做法是: 让业务层负责创建sqltranscation
    在数据访问层需要用到事务的函数添加一个sqltranscation参数
    我发现很多开源成熟的系统都是采用这种方式来处理业务层的事务。
    但总觉的怪怪的。。。
     回复 引用 查看   
  36. #36楼 Michael_Xu      2009-10-30 10:58
    非常好的文章,是自己以后设计、开发项目的标本.
     回复 引用 查看   
  37. #37楼 曹赛楠      2009-10-30 11:01
    期待楼主的后篇啊~~~~~~~~~~~~~~~~~
     回复 引用 查看   
  38. #38楼 Tonny Lau      2009-10-30 11:16
    楼主能够站在用户角度写技术文章,很好!写内容的也不错,很赞!文章夹杂自己深考,很佩服!
     回复 引用 查看   
  39. #39楼 阿K&LiveCai      2009-10-30 11:25
    静静地敲上支持的语句,

    呵呵,没有技术水平,评论。呵呵
     回复 引用 查看   
  40. #40楼 Kevin Zou      2009-10-30 12:11
    對於樓主將數據訪問層歸屬於業務邏輯層深表讚同。業務邏輯應該分為靜態的描述和動態的行為,前者一般通過關系數據庫完成,後者則是通過如c#,procedure,trigger程式完成
     回复 引用 查看   
  41. #41楼 超晨      2009-10-30 14:19
    难得的好文
    实际上之所以好多人有这个困惑,主要来自于项目产品上只是简单的UI+DAL,很大的原因是没有使用多种数据库的需求、没有使用多种UI的需求。所以对业务逻辑自然而然没有意识。分不清楚。

    另外就是表现层也有自己的逻辑。
    表现层的逻辑是业务的显示逻辑。正如LZ所说,业务逻辑应该只是简单的把正确数据交给UI,UI也应该只是把校验后的正确数据简单的传给业务。深层次的重复校验这些操作的确应该交给业务来做。

    因此UI层应该是这样的

    UI=数据校验逻辑+数据显示逻辑

    把现有的几种流行UI拿出来罗列,就知道如何分层了。
    webform
    mvc
    c/s
    flex
    silverlight
    wap2.0

    可以想象,如果没有业务逻辑,直接从UI上搜集来的数据就地处理到数据库的话,工作量是无法想象的。因此,根据产品项目性质的不同,你可以选择ui+dal,也可以选择三层,也可以ui内混合处理到数据库,关键看你是否有多UI或多数据库的需求变更。

    至于用不用存储过程,我认为适当即可。不必非SQL或者非SP,设想一下,一个上线的系统,需要处理某个东西,是SP内改一下方便还是重新编译上传系统?某些情况下,可能前者是合适的选择。
     回复 引用 查看   
  42. #42楼 没必要讲的这么深奥吧?[未注册用户]2009-10-30 14:55
    引用超晨:
    难得的好文
    实际上之所以好多人有这个困惑,主要来自于项目产品上只是简单的UI+DAL,很大的原因是没有使用多种数据库的需求、没有使用多种UI的需求。所以对业务逻辑自然而然没有意识。分不清楚。
    ...

     回复 引用   
  43. #43楼 LeonSun      2009-10-30 14:58
    可以就Domain Model详细说说么
     回复 引用 查看   
  44. #44楼 曾小舟      2009-10-30 15:47
    写得好。。
     回复 引用 查看   
  45. #45楼 alex-lee-lee[未注册用户]2009-10-30 15:49
    我对业务逻辑的理解是那就是算法。比如“我通过ATM取钱”这个业务,要先输入密码->决定取多少->出钞->打印单据,这些就是这个业务的规则,画成图,就是流程图、算法。因此,算法就是业务的逻辑。
    不知理解的对不对。那位大牛,给我指点下,我想知道对不对。另外,我喜欢面向过程编程,喜欢画流程图(以前喜欢面向对象这个,现在厌倦了,好像面向过程没有造成软件危机,面向对象也没有解决软件危机)。
     回复 引用   
  46. #46楼 Rainbow      2009-10-30 16:11
    非常不错的文章。赞。。。
     回复 引用 查看   
  47. #47楼 winter-cn      2009-10-30 17:46
    真是写的太好了

    我觉得有些软件 业务逻辑就是UI 比如浏览器 播放器
    有些软件 业务逻辑就是数据 比如编译器

    三层一般是面向某一特定非计算机领域的应用软件 计算机发展的再多 它的核心功能也只有2个:存储和计算 业务逻辑就是针对一个特定的应用场景如何存储和计算的问题 当然为了让非计算机专业人员使用 必须提供UI 把这些横向解耦 自然分为三层
     回复 引用 查看   
  48. #48楼 认同楼主广义的认知[未注册用户]2009-10-30 17:58
    引用winter-cn:
    真是写的太好了

    我觉得有些软件 业务逻辑就是UI 比如浏览器 播放器
    有些软件 业务逻辑就是数据 比如编译器

    三层一般是面向某一特定非计算机领域的应用软件 计算机发展的再多 它的核心功能也只有2个:存储和计算 业务逻辑就是针对一个特定的应用场景如何存储和计算的问题 当然为了让非计算机专业人员使用 必须提供UI 把这些横向解耦 自然分为三层

    “业务逻辑”与“业务逻辑层”应当是两个概念。
     回复 引用   
  49. #49楼 qmxle      2009-10-30 18:34
    我对存储过程的理解是:把刀拿到菜那里去,还是把菜拿到刀这儿来。比喻中的“刀”就是处理数据的逻辑,“菜”就是要处理的数据。
    如果“菜”很少,但是“刀”很复杂,那还是把菜拿到刀这儿来比较靠谱,就是说把数据读取到内存中,然后处理。
    但是,如果“菜”很多,但是“刀”很简单,那我觉得还是把刀拿到菜那里去,就是说在数据库中(使用存储过程)直接处理数据。毕竟从数据库中读取一堆数据,却只是为了求和,那还是用SUM()函数直接获取结果比较好。
    区分的方法可能很模糊,欢迎大家交流。
     回复 引用 查看   
  50. #50楼 怪怪      2009-10-30 20:38
    老兄这篇文章上的错误很多...

    比如关于CRUD和业务的隶属关系及有没有“权威定义”这个问题,还有一些其它的观点也和已经黑纸白字的知识有悖。

    简单转述一下以前思归他们讨论的时候说的:我们先假设一个永不停机、无限内存的机器,一经创建则一切都是已经存在的对象(就好比生产出一台汽车然后它就在那里),在这个基础上来进行设计。

    对于那些与此无关但不得不出现的的东西,是以Controller等等形式存在在边界上的:

    考虑到现实中没有这样的机器,我们需要持久化、需要载入到内存中,从此,开始产生如何ORM之类的问题;结合项目具体情况,对这一部分进行实现(极端情况下的目标是尽量透明,好似根本没有CRUD,就像那台用不停机、无限内存的机器一样)。

    妈的,说了我不是讲方法论及方法论的内容的角色,又破戒了。就此打住。

    老兄的文章写的确实很规范,而且也有一套说的通的道理。以至于楼上LS一水儿很有经验的兄弟都说LZ的文章“太好了”,我都不知道应该怎么评价了。

    我上面的话完全脱离我方法论反对者的地位,恰恰是站在方法论圈子内说的。下面的话站在另外一个方面来说。

    我觉得领域的角度来看问题有点脱离问题的实质。实际上我们可以想象没有计算机的世界。有人填表、有人收表、有人对表中的内容进行计算并填另一张表,然后再传给下一个收表的;有时候表需要放到一个大仓库里摆起来,并分门别类给以索引。

    计算机软件的业务逻辑的实质就是把这一个过程自动化,其中人能被代替的部分由程序负责。从这个视角去看,一切就要清晰很多:因为从来不存在有着“丰富内容”的表,自然也就不存在疑惑。

    但是到实施、编制软件的时候,这些“没有计算机时候”的表,是否还是那个形式,是否以实体的方式自己带有根据自己内容可以进行的计算和转发规则,这些都是根据具体情况进行决定的。所以这个视角和采用面向对象作为工具并不相悖。
     回复 引用 查看   
  51. #51楼 怪怪      2009-10-30 20:52
    忍不住多说两句:

    为什么楼主会认为数据访问是业务逻辑的一部分,对一个极端fans来说肯定是因为LZ不够专业。站在LZ正在介绍的这些词汇的角度上来说,可能有那么一点;但事实实际上不是这样。

    在进行一个设计之前,首先要定一个基调。

    如果一个应用是数据驱动的,或者说以数据驱动来看,是更加合理的视角,那么持久本身*就是*业务逻辑(而不仅仅是一部分),持久本身*就表达了*业务逻辑。(另一个视角上面的帖子已经说了)

    在这种情况下,恰恰相反的,那些非持久层的代码,才是用来辅助的小工具。很多极其成功的设计都是这样的。

    对于这种设计,LZ对存储过程的评述又是有误的:存储过程并非为了效率,仅仅是为了业务逻辑呆在他该呆的地方;而效率仅仅是因为采取了正确的做法而得到的一个肯定罢了。

    最后多说一句,虽然LZ这篇文章在一定的角度上高屋建瓴,但是如果LZ不是为了传达自己的理解,而是为了解释已有知识,恐怕还是暂停的好。

    如果为了讲解自己的一套体会(你的理解未必就是行不通的),最好也和已有知识划清界限,避免混淆。(这正是因为你写的太好了)

    最后再说一句我体会,虽然妈的、又破戒了:从实践上来看,一个系统当然可以既包括数据驱动的部分、又包括领域驱动的部分;但是从各自来说、还有从学习掌握各自的知识(虽然我根本不鼓励这种学习)来讲,不能带着数据驱动的遗留去看领域驱动、也不能带着领域驱动的偏见去看数据驱动。

    否则一个可能的情况是,总是在两边徘徊,也就总是发现新的心得而若有所悟,却总是不好把握其中一方的实质;而且很有可能的是,我们还不知道自己已经误解了所有这两方。
     回复 引用 查看   
  52. #52楼[楼主] EricZhang(T2噬菌体)      2009-10-30 21:27
    @怪怪

    多谢你耐心的回复。我仔细看了好几遍,感觉很有深度,一时还不能完全理解。

    不过请放心,我在写文章时,将个人理解和既有理论是划开的。在陈述既有理论时,我会直接陈述,而在陈述个人理解时,我都会在前面加“个人认为”、“个人觉得”之类的词,甚至在重要的地方会专门说明“个人理解,请批判阅读”。希望这样避免大家将我不成熟的理解和大师们已有的理论混为一谈。
     回复 引用 查看   
  53. #53楼 Ivony...      2009-10-30 22:10
    引用EricZhang(T2噬菌体):
    @怪怪

    多谢你耐心的回复。我仔细看了好几遍,感觉很有深度,一时还不能完全理解。

    不过请放心,我在写文章时,将个人理解和既有理论是划开的。在陈述既有理论时,我会直接陈述,而在陈述个人理解时,我都会在前面加“个人认为”、“个人觉得”之类的词,甚至在重要的地方会专门说明“个人理解,请批判阅读”。希望这样避免大家将我不成熟的理解和大师们已有的理论混为一谈。



    其实我也挺喜欢怪怪的回复的。。。。

    不过感觉很多时候,他的回复并不是完全的针对主题,或者说主题永远只是他回复的引子而不是全部。所以很多时候要脱离了博客的主题来看待他的回复。


    至于怪怪所说的:“如果为了讲解自己的一套体会(你的理解未必就是行不通的),最好也和已有知识划清界限,避免混淆。(这正是因为你写的太好了)”。我倒是有些体会。但理解却和怪怪不同,我是觉得正是由于博主的想法代表了大部分人的想法。在此基础上加以论证和阐述,固然有说仅代表个人观点,但大家会不自觉的认为:嘿,果然大牛和我想的一样。
    如果能跳出特定领域,从多个视角看待问题,则更能引人思考。
     回复 引用 查看   
  54. #54楼 怪怪      2009-10-30 22:12
    @EricZhang(T2噬菌体)
    不要在乎大师,凭你的认真,你也可能成为大师。关键在于小心混淆,这个地方对自己和对别人都不利。

    因为我们自己也要阅读其他人的文章,采用了相似的词汇而内涵稍有不同,就会产生误解。这时候读的东西越多,反而就越混乱了。
     回复 引用 查看   
  55. #55楼 Ivony...      2009-10-30 22:19
    引用怪怪:
    @EricZhang(T2噬菌体)
    不要在乎大师,凭你的认真,你也可能成为大师。关键在于小心混淆,这个地方对自己和对别人都不利。

    因为我们自己也要阅读其他人的文章,采用了相似的词汇而内涵稍有不同,就会产生误解。这时候读的东西越多,反而就越混乱了。



    无条件全面赞同。。。。
     回复 引用 查看   
  56. #56楼 Ivony...      2009-10-30 22:50
    受怪怪影响,我也发表一些尖锐的观点。

    虽然说是受怪怪影响,但我的观点和他却不尽相同,我是个俗人,对其方法论的反对者自我定位也不以为然,但我们的观点好像并没有冲突,他在方法论外,我在方法论内。谈谈自己的观点。


    其实与LZ的理解恰恰相反,我的思维碎片中提到,LZ在一个特定的领域讨论业务逻辑。并不是说业务逻辑在其他领域依然存在,而恰恰是不应存在。

    或许是我的思维过于混乱,表达也有一些问题。是的,我承认我们应该跳出这些领域来讨论业务逻辑。但我的目的却是希望在跳出领域后,我们会发现业务逻辑并不独立且没有明确边界。

    其实软件的功能每年都在发生改变,软件在改变我们生活的同时也在改变软件自身。或许我们今天还在讨论有没有永不停机,无限内存的机器;明天内存中的对象和持久化的边界就会变得模糊。这并没有什么不现实,将很少被用到的对象自动存档,引用不仅能检索内存。
    因为十几年前C++程序员也如我们一样困惑能不能创建了对象不必关心其生存周期,不必考虑销毁问题,不必考虑内存泄漏和碎片溢出。十几年后的今天我们new对象的时候从来没考虑过内存和其他。

    名词发明的原因是因为当时有那么个东西,而时间会将那个东西残忍的带走而名词却被留了下来。

    时光荏苒,新的方法论和开发哲学层出不穷,如果从现在流行的领域模型分析手法来看,业务逻辑层是对领域模型赤裸裸的割裂。这并不是业务逻辑层出了什么问题,而是我们思想已经进化,工具却没有跟上的缘故。业务逻辑究竟是什么,这个问题并不重要。或许,在什么场景下,我们要分出业务逻辑以及业务逻辑层,这样的问题可能更接近业务逻辑的本质。在脱离背景(唐朝)的情况下,论证为什么杨玉环很胖却很美,总是有些别扭的。

    我的意思是,我们应该直接用批判的眼光来看待三层,而不是将我们的方法回归到以前,领域缩减到一定范畴,来讨论业务逻辑的价值。

    或者,我们干脆把整个三层的背景搬来,假设我们没有C#、没有这么强大的数据库,完成某个功能简单的商业软件订单。这样来看待业务逻辑层,论证其在这种背景下的合理性和经典性。


    或许N年后又会另一群程序员聚在一起讨论,什么是“数据访问”?什么是ORM?而我们在他们的世界里早已是传说。时间就是这样的残忍,,,,
     回复 引用 查看   
  57. #57楼 seek      2009-10-30 22:53
    LZ文章不错。
    讲述的也是十分标准的开发流程。
    虽然本人在一家CMM5的公司做开发(ERP),自认为心里还算是比较清楚各类层次的划分,但是LZ的文章帮助我进一步整理的了思路。感谢ING....
    说点自己对业务逻辑认识的小心得。我在公司做的最多的就是编写所谓的业务逻辑。个人觉得流行的各类XX体系中所谓的“业务逻辑层”其实在大规模产品的开发过程中是不存在的。或者说是一个抽象度过高的概念。
    据个例子。比如一张单据的开发,UI上当用户选择不同的币种信息时需要带出不同的汇率(调用后台BP取值),而进一步通过取到的汇率信息与用户界面录入的原币金额计算出本币金额展示给用户(通过注册前台js脚本)。这个简单的业务逻辑却需要前后台至少2层结构的共同配合才能完成(Ps:也许有人会说为什么不一次在后台BP里计算好本币返回给前台?想想看为什么?)。而业务逻辑层又体现在哪里?
    因此,本人觉得业务逻辑其实可能遍布在除数据访问/映射层外的其他层外。只要是变化度高的(很难被再次抽象),都应当被归属为业务逻辑。
     回复 引用 查看   
  58. #58楼 怪怪      2009-10-31 00:16
    @Ivony...
    分层可以被看作独立于领域设计之外的;是不是应该叫做分层,要从看待问题的视角、和实际实现的结构而定。不是说有层就不好或者有层就好。

    (对一些方法所规划的某种结构,看作一个地图上的、彼此来往的不同国家比层来的更加准确;对完全已经透明了的结构,确实没必要过多关注什么层不层的了,毕竟我们也没弄出一个内存操作层)

    打住。接下来你说的GC带来的优点,刚刚和别人讨论过:

    GC有其适用的地方,比如老兄接触的显然都是。但恰恰GC是很早以前提出的,而且早就实现了的。放下GC,甚至我们可以从栈上看到相似点:C++程序员无需delete一个栈中的int,对吧?

    那时候机器内存都很少,加入GC,那么你会发现无时无刻不在GC,机器就没法用了。那么现在其实情况也一样。

    当你关注嵌入式设备的时候,如果在上面做一个吃内存的应用,就会发现GC还是有成为障碍的可能;而这恰恰也是一个主流开发方向(当然,这不成为我工作在富裕内存环境下时还非要浪费精神关注内存的理由。)。

    我的意思是,时代啊这些只是表象罢了,手法也无需过于有倾向性,(除了在交流时)更不必太多顾及自己遵循了什么背叛了什么。还是问题带有的条件决定了它的解答。

    如爱因斯坦所说,正确的问题永远比它的解答更重要。

    @seek
    前台js脚本还是后台代码,不是分离各部分的标准。你可以把所有的东西都在js脚本中实现,然后ORM是远程的,照样可以将业务和界面分离。

    C/S结构下的经典MVC(区别于Web这种)不就是可以这么做的么?不过是使用的语言和做图方式不一样了罢了。

    独立出来的业务逻辑,当然也可以同时分布在前台或者后台。你前台掺和着写了,就是没独立(至少部分的);你前台也是分离出了业务逻辑和UI,就是独立的。

    如果确实独立了,只是业务逻辑部分(不用“层”这个词)同时部署在不同的地方罢了。如果没独立,呵呵,也不是什么大碍,满足了需求、考虑也到位就好。
     回复 引用 查看   
  59. #59楼 卡通一下      2009-10-31 07:54
    引用seek:
    ......
    而业务逻辑层又体现在哪里?
    因此,本人觉得业务逻辑其实可能遍布在除数据访问/映射层外的其他层外。只要是变化度高的(很难被再次抽象),都应当被归属为业务逻辑。

    认同!

    我认为业务逻辑与业务逻辑层是两个概念,同时它们又仅仅是个概念,或者是一个指南性的东西,并非是什么法则。过去没有这些东西时,我们的程序也做的很好。

    我曾做过的合同录入系统,是将文本合同录入微机进行管理。依据合同中的资料和整个项目的关系,我抽象出两个业务逻辑,一个是“客户信息”,另一个是“产品信息”。这两个被抽象出来的逻辑块,可以应用到项目中的其它子系统。当然,这两个业务逻辑也有与之对应的业务逻辑层。

    另外,我觉得讨论这个问题用不着引经据典,空讲理论似乎在打嘴仗,讲点实例就可以了。

    归纳、抽取、整合现实需求中相对独立的操作。
     回复 引用 查看   
  60. #60楼 赵一村      2009-10-31 10:59
    期待下文
     回复 引用 查看   
  61. #61楼 雨霖铃      2009-10-31 12:30
    您在学校里研究的是计算机软件与理论中的哪个方向啊
     回复 引用 查看   
  62. #62楼[楼主] EricZhang(T2噬菌体)      2009-10-31 13:57
    引用雨霖铃:您在学校里研究的是计算机软件与理论中的哪个方向啊

    软件体系结构及软件项目管理。比较虚的方向。。。
     回复 引用 查看   
  63. #63楼 zunge      2009-10-31 16:02
    概念分析相当清楚,相当的解惑!看来大家的对这个概念的认知过程竟然如此的相似!非常棒!
     回复 引用 查看   
  64. #64楼 Ivony...      2009-10-31 19:22
    @怪怪

    没有分歧。。。


    我们既可以说是因为我们所处的领域和条件不同了,使得GC什么的可以让我们忘记内存泄漏和其他。也可以说这是因为时代的原因,从我的角度看,时代是最大的动因,而非其他。

    简单的说,在十几年前,软件根本就没办法完成我们现代软件可以完成的工作,软件所涉及的领域比现在的局限性大得多。或者极端一点,我们再往前回溯十几年,所有的程序员都在做“嵌入式开发”,而现在这个已经不是软件的主流。再过几年,一块指甲盖大小的CPU拥有2、3G的主频,512k的二级缓存且自带1G内存,这个时候即使是所谓的嵌入式开发,也可以如我们一样不用考虑内存的问题了。

    当然,这还是看你在什么领域,如果你就是在开发GC,那你不可能不考虑内存、碎片等问题。

    领域(或环境条件)是问题的本因,时代只是表象。或者反过来,这两者并不矛盾,是从两个视角对同一问题的描述。
     回复 引用 查看   
  65. #65楼 一抹红      2009-10-31 20:45
    文章写的不错,LZ可不可以举个在业务逻辑层使用事务的例子啊
     回复 引用 查看   
  66. #66楼 怪怪      2009-11-01 03:17
    @Ivony...
    但咱们总不能说做嵌入式的是工作在80年代不是 :)

    @卡通一下
    若咱们认为各种方法论那么多废纸堆中仅有一两句我们喜欢的话是核心,说实在的我们完全没有必要再管那么多;就如你所说,没有这些的时候也很好、而且可以继续好下去。

    我确实反对在这些东西上耗费太多精力;但是一旦有人决定从中借鉴些什么,我也不认同不求甚解的态度。

    真实的情况是,任何一种方法论都很难谈得上是什么严格的理论,也并非一两句话就能代表整个著作的成功学。

    它们是一组可供实践的、已经具体到一定程度的做法。我们不能正确理解和不必一一遵循,是不同两码事。

    对于现有知识,我们既可以有一定继承、也可能会有很多批判;但是根本不知道人家说的是什么,这两者就都谈不上。拿着通用词汇却说着自己的话,那还不如不交流有价值。

    不叨扰LZ了,拿分走人~
     回复 引用 查看   
  67. #67楼 卡通一下      2009-11-01 07:40
    @怪怪

    已有的经历和固有的思维经常左右着我的想法。哈哈...

    你的方法论我是认同的,既然是方法,那必然会是多元的。

    从感性上升到理性,这是一个较漫长的过程,不是一两篇文章就能解决的,还是要通过亲身的实践。
     回复 引用 查看   
  68. #68楼 FrogTan      2009-11-01 20:59
    添加一个新的订单”——这是一条典型的“增”操作。在数据访问层面上,它的意义是“在表示订单的数据表里增加一条记录”;而在业务逻辑层面上,它的意义除了“领域内多了一个订单实体”外,还可能包括“根据业务规则判断是否是重复下单,根据金额对下订单客户的等级做相应提升、发送Email和短信通知客户等 ”。可以看到,业务层面上的“增”可能不仅是简单封装一个简单的插入记录,可能还要去做其他数据访问——提升用户等级,以及做一些非CRUD的业务操作 ——发送短信通知。
    -----------------
    恩,写的真好,突然想到自己最新做添加收藏的业务逻辑,结果就是写了添加收藏,都没考虑要收藏的东西是不是已经收藏了。
     回复 引用 查看   
  69. #69楼 asheng      2009-11-02 15:20
    @Bees
    我觉得 当然是分开 来比较好
     回复 引用 查看   
  70. #70楼 asheng      2009-11-02 15:38
    楼主分析得比较详细 忍不住赞一个~
     回复 引用 查看   
  71. #71楼 stubas[未注册用户]2009-11-02 17:59
    关于事务:一种是业务上的事务,另外一种 我们数据库上提到的事务(当然 msmq等其他‘资源’也可以纳入事务里)。

    1:业务上的事务,一般是持续一段时间,跨越若干个业务操作,必须你自己“显式”去实现它,例如工作流等
    2:技术上的那些事务 transactionScope等,没有特别需要说,只是保证 纯技术方面的操作(保存数据啊)的一致性
     回复 引用   
  72. #72楼 stubas[未注册用户]2009-11-02 18:23
    领域上CRUD绝对就是业务逻辑

    如果某新增逻辑很重要,你甚至需要在领域对象上使用有意义的方法名把该操作刻意标记出来(为什么要这样,这样出来的代码就是自说明的)

    为啥老是提数据库表,领域对象可以存储在对象数据库,xml格式,云端,甚至。。。。
    --------------------------------------------------

    大家都了解过解方程组,n个未知数的一次方程,有无数个解,但是这个无数个解,可有一组(乃至多组) 正交的解‘拼凑’得到任何一个解
    DDD就是要我们提炼这些 ‘正交’的领域对象
    DDD要求我们把业务逻辑分布在每个领域对象中去,这样做的必然结果是,任何的该领域业务逻辑无非就是 这些领域对象相互协作的结果

    这里说的协作又需要用到一种类,rup里他们叫做控制类(facade 外观 也是做这样的事情),甚至 工作流的角色就是用来协调这些领域对象的交互协作的

     回复 引用   
  73. #73楼 tan_Cool      2009-11-03 09:56
    不用存储过程好
    拥护不用存储过程
     回复 引用 查看   
  74. #74楼 Coder Lee      2009-11-03 10:02
    lz这样讲业务似乎有些局限。或多或少的局限于以数据库设计的形式讲lz对业务的理解。
    不知道lz是不是有先做数据库设计之后再做相关的开发工作的习惯。
    如果是这样的话,那么可能是把依赖顺置了。也即,设计工作应该是从上层的设计开始,然后才是数据库的设计。lz是不是考虑下用这样的设计思维形式讲解你对业务的理解呢?
     回复 引用 查看   
  75. #75楼[楼主] EricZhang(T2噬菌体)      2009-11-03 13:46
    引用Coder Lee:
    lz这样讲业务似乎有些局限。或多或少的局限于以数据库设计的形式讲lz对业务的理解。
    不知道lz是不是有先做数据库设计之后再做相关的开发工作的习惯。
    如果是这样的话,那么可能是把依赖顺置了。也即,设计工作应该是从上层的设计开始,然后才是数据库的设计。lz是不是考虑下用这样的设计思维形式讲解你对业务的理解呢?

    两年前的时候,习惯从数据库开始设计。近两年都是从上层开始设计了。即需求-交互-美工-页面-代码-数据库,有时会有迭代和回溯。
    我其实没想局限在数据库设计上讲业务逻辑,可能是我表达的不明确吧。
     回复 引用 查看   
  76. #76楼 想不明白[未注册用户]2009-11-03 18:43
    引用EricZhang(T2噬菌体):
    即需求-交互-美工-页面-代码-数据库,有时会有迭代和回溯。
    我其实没想局限在数据库设计上讲业务逻辑,可能是我表达的不明确吧。

    如果使用数据库,那先写代码后设计数据库,实在搞不明白代码如何写?
     回复 引用   
  77. #77楼 CareySon      2009-12-24 07:10
    拜读..我现在一直在想领域实体应该是仅仅只包含属性的简单实体还是应该包含属性方法事件的复杂实体?

    楼主怎么看?
     回复 引用 查看   
  78. #78楼 发香已散      2010-06-03 10:10
    怎么爽怎么来,根据经验前进
     回复 引用 查看   
  79. #79楼 伊牛娃      2010-06-03 12:07
    看了半天,慢慢嚼

    文章精彩,评论同样精彩
    ------
    引用tan_Cool:
    不用存储过程好
    拥护不用存储过程


    引用超晨
    ---超晨--
    至于用不用存储过程,我认为适当即可。不必非SQL或者非SP,设想一下,一个上线的系统,需要处理某个东西,是SP内改一下方便还是重新编译上传系统?某些情况下,可能前者是合适的选择。


    -------
    对于需要,依据条件 来进行变动,而且条件也比较复杂,我习惯使用sp,因为这样修改不需要重新编译dll,
     回复 引用 查看   
  80. #80楼 virus      2010-06-03 13:30
    这个好像是.NET Application Architecture Guide V2中的东西吧,那个不会是LZ写的吧
     回复 引用 查看   
  81. #81楼 春哥传教士      2010-06-25 15:47
    太强了!看了楼主的文章我厕所顿开。这篇文章对业务逻辑的阐述比很多书讲得都明白,受益匪浅。
     回复 引用 查看   
  82. #82楼 Julian's Blog      2010-09-16 18:48
    楼主不仅仅是技术牛人,而且也是文学达人。
     回复 引用 查看   
  83. #83楼 Jack Feng      2011-04-13 12:56

    说得很好,不过不是很赞同不要把业务操作写到存储过程中去。因为回滚是一个问题。
     回复 引用 查看   
  84. #84楼 freshfish      2011-05-23 23:22
    谢谢楼主
     回复 引用 查看   
  85. #85楼 空葫芦      2011-06-22 17:40
    非常好的文章!
    以前看到过一次,但是那是个doc文档,没有标明作者。
    原来是出自这里,要再看一遍文章和评论。
     回复 引用 查看   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1592568 7xziXkUYJdI=