我见到过一种三层模型,分为UI、BLL、DAL。此外还有一组Model类,用于封装实际的业务对象。这没什么特别的,多数三层模型都是这样。但是,这种三层模型有个特殊的地方,对于每一个描述业务对象的Model类,在BLL里基本上都有一个类对应,实时查询、检索等等操作。差不多就是个管理类吧。但如果深入到这些类内部,发现它们只是一组wrapper。其内部保有一个对象,该对象的类来自于DAL。而BLL中的这些类上的操作在DAL相对应的类上都有。BLL类实际只是在转发操作,而真正工作的,是DAL中的那一组类。
我觉得很奇怪,为什么要凭空锻造出这么一组毫无用处的类呢?得到的答案是:从MS的案例中学来的。诧异之余,我未免心中起疑,MS再差劲,也不至于直眉瞪眼地破坏DRY吧。肯定是这些家伙学艺不精,会错MS的意了。
不久前,公司来了一个应聘者,走的是.net路线,在外做过几个项目。我们出编程题考他,结果他做的程序的结构也是三层模型,居然和上面所说的结构一模一样,也是在BLL中放了一组无用的wrapper。关键是,此人和那个三层模型的创造者此前完全不可能相识。那么,只有两种可能。要么是他们以同样的方式错误理解了MS的案例;要么就是MS的案例本来就是这样的。
MS的案例究竟如何,我没有考证过,也无意去关心。我想到的是一个程序员如何开始学习编程。很多程序员喜欢从案例开始学习。从抄写代码,慢慢变为小修小改,然后逐步理解,最后开始单飞。但是,这里有个问题。程序员就像小鸟。小鸟会把第一眼看见的会动的东西当成妈妈,而程序员则会把最初学习的案例当成典范。
因而,程序员最初开始的编程学习就显得非常重要。一旦定型,以后很难改掉。一个程序员最初不应该从某些应用型的案例中开始学习。更多地应该把精力放在基本功上,像基本的编程原则、算法、范式等等。并且从一些小案例开始,比如写个小算法、小工具等等。此时的程序员还缺乏判断力,无法认清那些复杂案例中的问题和陷阱。上面提到的这种三层模型,我相信ms原意并非如此。但是,涉世不深的程序员很容易误解其中的用意,然后加以发挥。在没有正确引导的情况下,误入歧途。
可是,现实往往是残酷的。很多程序员并没有机会获得完善的培训。他们在大学里没有打好基础,来到工作单位就立刻投入开发工作,很多都是从接手和维护其他人的代码开始。企业希望以此快速地培养出程序员。但是这也往往使得那些代码中原本存在的缺陷被新手们充分吸收。老程序员往往无暇顾及那些新人。有时,甚至他们自身也未曾意识到存在的问题。这样,错误就一代接一代地传了下去。
指出了这些问题之后,我却不知道有什么好方法能够破解。我能想到的唯一方法就是,趁自己工作前,或者技术定型之前,打好基础,开拓眼界。不要迷信案例,带着怀疑的眼光和基本原则来看待他们。多问(不是在这里哈),多想,多google,多wiki,还有多上TopLanguage。:P
可是,现实往往是残酷的。很多程序员并没有机会获得完善的培训。他们在大学里没有打好基础,来到工作单位就立刻投入开发工作,很多都是从接手和维护其他人的代码开始。企业希望以此快速地培养出程序员。但是这也往往使得那些代码中原本存在的缺陷被新手们充分吸收。老程序员往往无暇顾及那些新人。有时,甚至他们自身也未曾意识到存在的问题。这样,错误就一代接一代地传了下去。
是这样,Model类代表着业务对象。每个model类有一个BLL类对应,起管理作用。但请注意,这里BLL中的类和DAL中的类的接口是一模一样的,BLL只是转发了操作。当DAL发生变化,BLL也相应地发生变化。这里根本的问题是,如果DAL类的接口和BLL一样,就表明有业务相关的内容进入DAL了。
实际上,这个三层模型把应该放在BLL中的东西放到了DAL中,而按规定,UI不应当越过BLL直接访问DAL,那么为了让UI得到服务,就不得不在BLL中放置包装类转发操作,以免造成跨层访问。
这样的做法造成的后果就是,无论是BLL变动,还是DAL变动,都将造成两个层面一起修改。
因而,程序员最初开始的编程学习就显得非常重要。一旦定型,以后很难改掉。一个程序员最初不应该从某些应用型的案例中开始学习。更多地应该把精力放在基本功上,像基本的编程原则、算法、范式等等。并且从一些小案例开始,比如写个小算法、小工具等等。
这个世界变化太快,特别是计算机行业,对于普通程序员大众(包括我),在很多时候是在用别人写的库,模型等等。除了一些自己真正关心的领域,其他的好像
都是不求甚解。恩拿来用,大概了解下背景知识。有时候其实这些库啊模型啊或许已经不十分适合现在实际情况。要想扩展出去深入的了解一下。却发现又是一个
宽广的天地。。时间和精力啊。。
我们也积累了一大堆老的存在各种问题的代码,不过采取了一个不是办法的办法。目前基本上新进来的人都是手把手带,老员工会review新员工的代码,同
时查看原来老的代码中的问题(粗看),然后维护一份BUG和FAQ,只要可能是问题的都记录在案,包括编程习惯,设计,模型缺陷,新的想法之类。后面新
进员工进来接触到相关领域就把相关的FAQ先通读一遍,让他知道他接触到的东西很有可能就是错的,带着怀疑开始他的工作(的确也维护掉了老程序代码中的
一堆东西,呵呵学习中重构)。诶,不过没有专人来维护这样的文档,到后面这个文档本身也变成了一个问题。。目前逐步写简单的维护系统和定义文档规范
中。。
扯开了,楼主的文章想到几句话:
1.活到老学到老。
2.带着发展的眼光看问题。
3.权威的不一定是正确的。
另外,随着tp的不断进步和完善,应该会越来越好的扮演好一个引导者的角色吧。希望各位大侠多点耐心分析解答问题。
不知道楼主是在什么样的阶段真正领悟到"我能想到的唯一方法就是,趁自己工作前,或者技术定型之前,打好基础,开拓眼界。不要迷信案例,带着怀疑 的眼
光和基本原则来看待他们"。我是在工作了蛮长一段时间后。经历了从X86平台到嵌入式平台。MS C++到linux下的C/C++开发以后。
这个世界变化太快,特别是计算机行业,对于普通程序员大众(包括我),在很多时候是在用别人写的库,模型等等。除了一些自己真正关心的领域,其他的好像
都是不求甚解。恩拿来用,大概了解下背景知识。有时候其实这些库啊模型啊或许已经不十分适合现在实际情况。要想扩展出去深入的了解一下。却发现又是一个
宽广的天地。。时间和精力啊。。
我们也积累了一大堆老的存在各种问题的代码,不过采取了一个不是办法的办法。目前基本上新进来的人都是手把手带,老员工会review新员工的代码,同
时查看原来老的代码中的问题(粗看),然后维护一份BUG和FAQ,只要可能是问题的都记录在案,包括编程习惯,设计,模型缺陷,新的想法之类。后面新
进员工进来接触到相关领域就把相关的FAQ先通读一遍,让他知道他接触到的东西很有可能就是错的,带着怀疑开始他的工作(的确也维护掉了老程序代码中的
一堆东西,呵呵学习中重构)。诶,不过没有专人来维护这样的文档,到后面这个文档本身也变成了一个问题。。目前逐步写简单的维护系统和定义文档规范
中。。
扯开了,楼主的文章想到几句话:
1.活到老学到老。
2.带着发展的眼光看问题。
3.权威的不一定是正确的。
另外,随着tp的不断进步和完善,应该会越来越好的扮演好一个引导者的角色吧。希望各位大侠多点耐心分析解答问题。
另外对莫老师说一下:分三层在逻辑上比较清晰。UIL只管显示,BLL只管业务逻辑,DAL只管数据访问,每一层都具有一定的责任。这也是跟面向对象的三个原则:"对象就是责任"、"针对变化封装之"、"高内聚,低耦合"相符合的。BLL的确是封装,但不仅仅是简单的封装吧,它通常要把DAL提供的接口组合起来并处理一些异常。举个例子,比如DAL提供了Insert、Delete、Query、Update四个接口,现在BLL有个取钱的接口Withdraw里面组合了Query、Update这两个接口并返回一个UIL需要的结果,则UIL直接调用这个接口就行了。当业务逻辑出现变化,比如在Query和Update中间要加个Insert,UIL不用改变任何代码。当然可以执意把这些代码写入UIL,甚至所有代码都写入UIL,这都行,无非就是UIL里头写个BL类,DA类什么的也都能够符合那些原则,问题是如果项目大了以后这样就很痛苦了。
另一方面,三层模型有效地发挥作用,需要有相对固定的需求,特别是业务对象的逻辑关系尽量少变动。而上层的变化尽量局限在业务过程的变化。但是,在我经历国的项目中,变化最多的反而是业务对象的结构和逻辑关系。用户最初的需求往往极不成熟,只有在开发到一定程度,甚至上线之后,才会得到真正有用的需求。而此时的需求同原始需求可能差着十万八千里,基本上都是根本性的变化。反倒是Withdraw这样的变化很少出现。这样的情况使得三层模型根本无用武之地,反而成了累赘。
此外,在实际项目中,ui同业务逻辑之间的关系比想象的要密切得多。两者之间任何一个的变化,往往会引发另一个的变化。比如,在一个录入界面中,业务逻辑需要增加一个业务对象的属性赋值,那么多半会要求用户给主相应的直或对象,这必然会引发ui的变化。同时,也会要求相应的业务逻辑接口增加参数,以容纳新的数据。正因为如此,实际情况中,程序员更多地倾向于将业务逻辑安置在ui中,便于维护。
面向对象有其原则,而编程亦有其原则。当它们两者之间发生冲突,就像那个三层模型那样,应当选择哪一个呢?
btw:商量一下哈,不要叫我"老师"行不:)。让我很紧张,不自在:)。在一个group里的都是兄弟姐妹,顶多叔伯姨舅:D。
我声明一下哈,大家叫我姓名,名字,老莫,都可以。如果想找个新鲜的,大学里别人叫我"长脚"(longshanks),我也很喜欢的:) 。还有家里的小名...。呃,小名就算了。:D
拜托,多谢了。:)
2008/12/10 莫华枫 <longsh...@gmail.com>
另一方面,三层模型有效地发挥作用,需要有相对固定的需求,特别是业务对象的逻辑关系尽量少变动。而上层的变化尽量局限在业务过程的变化。但是,在我经历国的项目中,变化最多的反而是业务对象的结构和逻辑关系。用户最初的需求往往极不成熟,只有在开发到一定程度,甚至上线之后,才会得到真正有用的需求。而此时的需求同原始需求可能差着十万八千里,基本上都是根本性的变化。反倒是Withdraw这样的变化很少出现。这样的情况使得三层模型根本无用武之地,反而成了累赘。
此外,在实际项目中,ui同业务逻辑之间的关系比想象的要密切得多。两者之间任何一个的变化,往往会引发另一个的变化。比如,在一个录入界面中,业务逻辑需要增加一个业务对象的属性赋值,那么多半会要求用户给主相应的直或对象,这必然会引发ui的变化。同时,也会要求相应的业务逻辑接口增加参数,以容纳新的数据。正因为如此,实际情况中,程序员更多地倾向于将业务逻辑安置在ui中,便于维护。
面向对象有其原则,而编程亦有其原则。当它们两者之间发生冲突,就像那个三层模型那样,应当选择哪一个呢?
btw:商量一下哈,不要叫我"老师"行不:)。让我很紧张,不自在:)。在一个group里的都是兄弟姐妹,顶多叔伯姨舅:D。
我声明一下哈,大家叫我姓名,名字,老莫,都可以。如果想找个新鲜的,大学里别人叫我"长脚"(longshanks),我也很喜欢的:) 。还有家里的小名...。呃,小名就算了。:D
拜托,多谢了。:)
我没有从事过很大的项目,所以不能够理解这段话所描述的困难。但我明白,变化是永恒的。你不可能不考虑需求的变化,但考虑变化会使系统产生很大的冗余,复杂性也随之提高,这样BUG也会增多,这确实是考验软件管理者的设计的。令人惊奇的是UNIX的设计!当初Ken只是想"玩"一把,完全是处于自己兴趣,并没有考虑很多变化,没有作太多设计,而事实证明UNIX是多么成功,无独有偶,LINUX也是,刚开始的版本只是能够运行而已,需要什么功能都是现加入,LINUX依然是成功的。而具有讽刺意味的是UNIX的前辈MULTICS,作了那么多充足的估计,考虑到了无数的变化,最后依然因为它的复杂性而失败。然而,事实是现在大多数成功的软件都是考虑周全的结果。令人困惑的是,在复杂性和简洁之间如何抉择?
ps:我们这流行:昵称=名字的最后一个字 + "子",比如,徐杰被叫做"杰子",那么你应该被叫做"枫子"喽:D
令人惊奇的是UNIX的设计!当初Ken只是想"玩"一把,完全是处于自己兴趣,并没有考虑很多变化,没有作太多设计,而事实证明UNIX是多么成功,无独有偶,LINUX也是,刚开始的版本只是能够运行而已,需要什么功能都是现加入,LINUX依然是成功的。而具有讽刺意味的是UNIX的前辈MULTICS,作了那么多充足的估计,考虑到了无数的变化,最后依然因为它的复杂性而失败。然而,事实是现在大多数成功的软件都是考虑周全的结果。令人困惑的是,在复杂性和简洁之间如何抉择?
借你这段说几句。我上了四年大学,当时学的最开心的课程是微积分,计算理论,数据结构,操作系统理论等等偏理论的课,而那些实践性比较强的比如c++,java啥的,基本上就是在脑子里走个过场。目前工作所需的--恕我直言--“小伎俩”,都是在工作后学会的。我认为大学的目的在于培养学生的独立思考能力,训练他们如何成为一个合格的“现代公民”,虽然社会生产实践能力也是现代公民应有素质之一,但绝不会是全部。反观目前的高校,学生都拼命的想找个实习的机会,尽早的成为熟练工以便毕业能找个好工作;老师则拼命的接各类项目以便,你知道,赚更多的钱。他们统统对人类积累的上百年的智慧视而不见。我不知道这是一个转型期社会的“特色”,还是中国人又缺乏了某类精神特质。
我回这个帖子是因为看到暴龙同学在抱怨学校,也想跟着抱怨一下,没切主贴的题,见谅。
我没有从事过很大的项目,所以不能够理解这段话所描述的困难。但我明白,变化是永恒的。你不可能不考虑需求的变化,但考虑变化会使系统产生很大的冗余,复杂性也随之提高,这样BUG也会增多,这确实是考验软件管理者的设计的。令人惊奇的是UNIX的设计!当初Ken只是想"玩"一把,完全是处于自己兴趣,并没有考虑很多变化,没有作太多设计,而事实证明UNIX是多么成功,无独有偶,LINUX也是,刚开始的版本只是能够运行而已,需要什么功能都是现加入,LINUX依然是成功的。而具有讽刺意味的是UNIX的前辈MULTICS,作了那么多充足的估计,考虑到了无数的变化,最后依然因为它的复杂性而失败。然而,事实是现在大多数成功的软件都是考虑周全的结果。令人困惑的是,在复杂性和简洁之间如何抉择?
ps:我们这流行:昵称=名字的最后一个字 + "子",比如,徐杰被叫做"杰子",那么你应该被叫做"枫子"喽:D
早期设计者们遵循着最质朴、最根本的软件设计理念,但它们却是最本质的。而后来者继续秉承他们的思想发扬光大。这正是现在很多程序员所应当学习的。UNIX设计者们并未炫耀某种先进的模式或者技术,他们踏踏实实地、一步一趋地遵循着基本的设计原则(KISS、DRY、Simple Interface、Small is beautiful...)。而所使用的技术甚至是土得掉渣的。
多了一层没有意义的wrapper, 那又怎么样呢?真正影响到了什么呢?performance? 得了吧,还有更多的地方值得tuning.
以前读过印度啊三的代码(有嵌入式的,也有企业软件的),大都是这种路数,我觉得反而是"规范",变得亲切易读了呢。
代码工业化的今天,何必呢。
On 12月10日, 上午11时26分, "莫华枫" <longshank...@gmail.com> wrote:
> 2008/12/10 li li <popil1...@gmail.com>
>
>
>
> > 另外对莫老师说一下:分三层在逻辑上比较清晰。UIL只管显示,BLL只管业务逻辑,DAL只管数据访问,每一层都具有一定的责任。这也是跟面向对象的三个原则-:"对象就是责任"、"针对变化封装之"、"高内聚,低耦合"相符合的。BLL的确是封装,但不仅仅是简单的封装吧,它通常要把DAL提供的接口组合起来并处理-一些异常。举个例子,比如DAL提供了Insert、Delete、Query、Update四个接口,现在BLL有个取钱的接口Withdraw里面组合了Q-uery、Update这两个接口并返回一个UIL需要的结果,则UIL直接调用这个接口就行了。当业务逻辑出现变化,比如在Query和Update中间要加-个Insert,UIL不用改变任何代码。当然可以执意把这些代码写入UIL,甚至所有代码都写入UIL,这都行,无非就是UIL里头写个BL类,DA类什么的-也都能够符合那些原则,问题是如果项目大了以后这样就很痛苦了。
>
> 说的对。这些原本就是多层模型的愿景。但是,在实际中却出现了BLL中没东西可放的情况。这又很多原因。主要是由于BLL的部分功能被抽离到其他两层。为什么会-这样?这就涉及到分层的本质。如果Withdraw接口被若干UI组件使用,那么这种抽象是有益的。因为Withdraw有所变化时,只需修改一个地方即可。但-是,在实际情况中,我们发现,这种公用的情况不多。被一个UI模块使用的业务逻辑要多于被多个模块使用的业务逻辑。这样,单独维护这些业务逻辑就没什么意义,但-增加了维护的难度。
> 而且,有些被多个模块使用的业务逻辑在开发,甚至使用的过程中发生变化,而无法被多个模块使用。麻烦的是,这些分化出来的业务逻辑在某些方面又有共同的地方,这-样的重构给开发工作带来很大的麻烦。所以,很多程序员宁愿把业务逻辑放在ui里,一旦出现公用的情况,在把它抽离出来。为了方便,他们也就随手把这些公共模块留-在了ui中。
> 另一方面,三层模型有效地发挥作用,需要有相对固定的需求,特别是业务对象的逻辑关系尽量少变动。而上层的变化尽量局限在业务过程的变化。但是,在我经历国的项-目中,变化最多的反而是业务对象的结构和逻辑关系。用户最初的需求往往极不成熟,只有在开发到一定程度,甚至上线之后,才会得到真正有用的需求。而此时的需求同-原始需求可能差着十万八千里,基本上都是根本性的变化。反倒是Withdraw这样的变化很少出现。这样的情况使得三层模型根本无用武之地,反而成了累赘。
> 此外,在实际项目中,ui同业务逻辑之间的关系比想象的要密切得多。两者之间任何一个的变化,往往会引发另一个的变化。比如,在一个录入界面中,业务逻辑需要增-加一个业务对象的属性赋值,那么多半会要求用户给主相应的直或对象,这必然会引发ui的变化。同时,也会要求相应的业务逻辑接口增加参数,以容纳新的数据。正因-为如此,实际情况中,程序员更多地倾向于将业务逻辑安置在ui中,便于维护。
> 面向对象有其原则,而编程亦有其原则。当它们两者之间发生冲突,就像那个三层模型那样,应当选择哪一个呢?
>
> btw:商量一下哈,不要叫我"老师"行不:)。让我很紧张,不自在:)。在一个group里的都是兄弟姐妹,顶多叔伯姨舅:D。
> 我声明一下哈,大家叫我姓名,名字,老莫,都可以。如果想找个新鲜的,大学里别人叫我"长脚"(longshanks),我也很喜欢的:)
> 。还有家里的小名...。呃,小名就算了。:D
> 拜托,多谢了。:)
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/
我见到过一种三层模型,分为UI、BLL、DAL。此外还有一组Model类,用于封装实际的业务对象。这没什么特别的,多数三层模型都是这样。但是,这种三层模型有个特殊的地方,对于每一个描述业务对象的Model类,在BLL里基本上都有一个类对应,实时查询、检索等等操作。差不多就是个管理类吧。但如果深入到这些类内部,发现它们只是一组wrapper。其内部保有一个对象,该对象的类来自于DAL。而BLL中的这些类上的操作在DAL相对应的类上都有。BLL类实际只是在转发操作,而真正工作的,是DAL中的那一组类。
我觉得很奇怪,为什么要凭空锻造出这么一组毫无用处的类呢?得到的答案是:从MS的案例中学来的。诧异之余,我未免心中起疑,MS再差劲,也不至于直眉瞪眼地破坏DRY吧。肯定是这些家伙学艺不精,会错MS的意了。
不久前,公司来了一个应聘者,走的是.net路线,在外做过几个项目。我们出编程题考他,结果他做的程序的结构也是三层模型,居然和上面所说的结构一模一样,也是在BLL中放了一组无用的wrapper。关键是,此人和那个三层模型的创造者此前完全不可能相识。那么,只有两种可能。要么是他们以同样的方式错误理解了MS的案例;要么就是MS的案例本来就是这样的。
MS的案例究竟如何,我没有考证过,也无意去关心。我想到的是一个程序员如何开始学习编程。很多程序员喜欢从案例开始学习。从抄写代码,慢慢变为小修小改,然后逐步理解,最后开始单飞。但是,这里有个问题。程序员就像小鸟。小鸟会把第一眼看见的会动的东西当成妈妈,而程序员则会把最初学习的案例当成典范。
因而,程序员最初开始的编程学习就显得非常重要。一旦定型,以后很难改掉。一个程序员最初不应该从某些应用型的案例中开始学习。更多地应该把精力放在基本功上,像基本的编程原则、算法、范式等等。并且从一些小案例开始,比如写个小算法、小工具等等。此时的程序员还缺乏判断力,无法认清那些复杂案例中的问题和陷阱。上面提到的这种三层模型,我相信ms原意并非如此。但是,涉世不深的程序员很容易误解其中的用意,然后加以发挥。在没有正确引导的情况下,误入歧途。
可是,现实往往是残酷的。很多程序员并没有机会获得完善的培训。他们在大学里没有打好基础,来到工作单位就立刻投入开发工作,很多都是从接手和维护其他人的代码开始。企业希望以此快速地培养出程序员。但是这也往往使得那些代码中原本存在的缺陷被新手们充分吸收。老程序员往往无暇顾及那些新人。有时,甚至他们自身也未曾意识到存在的问题。这样,错误就一代接一代地传了下去。
指出了这些问题之后,我却不知道有什么好方法能够破解。我能想到的唯一方法就是,趁自己工作前,或者技术定型之前,打好基础,开拓眼界。不要迷信案例,带着怀疑的眼光和基本原则来看待他们。多问(不是在这里哈),多想,多google,多wiki,还有多上TopLanguage。:P
多了一层没有意义的wrapper, 那又怎么样呢?真正影响到了什么呢?performance? 得了吧,还有更多的地方值得tuning.
以前读过印度啊三的代码(有嵌入式的,也有企业软件的),大都是这种路数,我觉得反而是"规范",变得亲切易读了呢。
代码工业化的今天,何必呢。
On 12月10日, 下午3时38分, "莫华枫" <longshank...@gmail.com> wrote:
> 2008/12/10 li li <popil1...@gmail.com>
>
> 还有一点,UNIX的成功看似神奇,但蕴含着必然。早期设计者们遵循着最质朴、最根本的软件设计理念,但它们却是最本质的。而后来者继续秉承他们的思想发扬光大 。这正是现在很多程序员所应当学习的。UNIX设计者们并未炫耀某种先进的模式或者技术,他们踏踏实实地、一步一趋地遵循着基本的设计原则(KISS、DRY、 Simple
> Interface、Small is beautiful...)。而所使用的技术甚至是土得掉渣的。
大道至简的道理。
然则师傅带入门,修行还是靠自身。同样的一个东西,个人得到的领悟是不一样的。
不要陷入技术和权威的迷区就好。
程序员毕竟应该是一份创造性的职业,在积累了一定的经验以后,要鉴定的走创造的道路,而不只是单纯的模仿。
考虑未来业务的扩展,一定需要wrapper和空空的BLL吗?或者说,只有wrapper才能提供未来业务的扩展吗?
这里,我给出另一个途径。我们可以先去掉BLL,或者将DAL中与业务有关的内容移到BLL中。也可以理解为由UI直接访问DAL。这样,所有基本的业务对象的操作由UI直接从DAL处获得,比如业务对象的增删改查等等。然后,对于复杂的业务,比如需要组合多个基本业务操作的逻辑,在UI中实现。随着业务的复杂化,某些业务逻辑会由多个UI所共享,那么就将这些代码分离出来,形成一个模块,或者UI中的亚层。或许这个亚层也可以称为BLL(实际上它叫什么有什么差别吗?),但按照标准的分层理论,它够不成一个层次,因为他没有将上层和下层隔完全离开。不过,这对于实际应用没有什么影响。即便在那些标准的BLL中,也存在很多操作,如复杂的查询,需要绕开DAL直接访问数据库。因而这些三层模型也并非严格意义上的分层。
再有,这些wrapper的存在对代码修改的难度有多大的影响呢?让我们假设有一个业务逻辑A被UI调用,并且只有一个使用点。现在可以考察一下,当A发生变动时(暂时不考虑接口的变动,因为接口一变,UI通常都得改),究竟是A放在UI中修改起来麻烦呢,还是A放在单独的BLL中麻烦呢?实际上,两这是一样的。因为无论A在哪里,我只需修改一个地方,要么在UI里,要么在BLL里。
所以说,并没有必要在BLL中塞进wrapper,以提高可扩展性。实际上,UI和DAL的分离已经提供了足够的扩展能力,而无须BLL中的wrapper来增加负担。
考虑未来业务的扩展,一定需要wrapper和空空的BLL吗?或者说,只有wrapper才能提供未来业务的扩展吗?"只有"这个绝对量的提问是没有意义的.
这里,我给出另一个途径。我们可以先去掉BLL,或者将DAL中与业务有关的内容移到BLL中。也可以理解为由UI直接访问DAL。这样,所有基本的业务对象的操作由UI直接从DAL处获得,比如业务对象的增删改查等等。然后,对于复杂的业务,比如需要组合多个基本业务操作的逻辑,在UI中实现。随着业务的复杂化,某些业务逻辑会由多个UI所共享,那么就将这些代码分离出来,形成一个模块,或者UI中的亚层。或许这个亚层也可以称为BLL(实际上它叫什么有什么差别吗?),但按照标准的分层理论,它够不成一个层次,因为他没有将上层和下层隔完全离开。不过,这对于实际应用没有什么影响。即便在那些标准的BLL中,也存在很多操作,如复杂的查询,需要绕开DAL直接访问数据库。因而这些三层模型也并非严格意义上的分层。如果这个程序只有你一个人写,那你写在哪里都没问题.如果是一个team来做的话,我不知道你是准备让他们自由发挥,还是team来硬性规定用这种方式来写.即使你统一team来做这个规定,项目被别的team接收或者进入新人的话又要投入精力,过一年后来个2期,你又找到了一个可用的方法来写,你会用你新的方式还是这次方式的?既然已经有这样的一个事实默认的n层分布,而且大家都熟悉它,为什么你还要再来自己发明一套?
再有,这些wrapper的存在对代码修改的难度有多大的影响呢?让我们假设有一个业务逻辑A被UI调用,并且只有一个使用点。现在可以考察一下,当A发生变动时(暂时不考虑接口的变动,因为接口一变,UI通常都得改),究竟是A放在UI中修改起来麻烦呢,还是A放在单独的BLL中麻烦呢?实际上,两这是一样的。因为无论A在哪里,我只需修改一个地方,要么在UI里,要么在BLL里。基本上,在wrapper中对修改的代码进行的测试要比ui容易的多,也就影响到你代码修改的效率.开发不只是写代码.
所以说,并没有必要在BLL中塞进wrapper,以提高可扩展性。实际上,UI和DAL的分离已经提供了足够的扩展能力,而无须BLL中的wrapper来增加负担。绝对的必要肯定不会,但是相对优异还是有的. 至于你说wrapper是负担,我不知道到底有多少人在手工写这些wrapper.没有小工具?自己写个.
这一个线索的贴子讨论得相当精彩。我潜水看这个系列,印证我自己在工作中的体会,也都受益匪浅。呵呵。近期在做WEB开发,WEB也有MVC三个层次的
划分,其中的View、Control、Model就大致对应于UIL、BLL、DAL吧。基本能够套用这个讨论之中的很多观点。
关于这个“同样的东西,在wrapper中测试,比在UI中的一个模块中测试,哪种更加方便高效”的问题,就我近期遇到的体会补充两句。同样的东西,放
在View中实现与放在Control中实现,代码量基本持平;将来业务变更时,要更改也是只更改一个地方。这方面,没有什么差别。但从测试的角度说,
业务逻辑最好还是放在Control层,会比较方便。因为大多数WEB框架的control层都是实现为一批功能函数,可以用成熟的代码级
UnitTest手段来测试。如果是放在View层(即UI层),那么测试的时候,就涉及到要在一定程度上模拟浏览器的行为甚至模拟鼠标键盘操作才能进
行测试,就比较麻烦了。
说上面这些,意思并不是用于反对老莫的一系列观点。相反,我对老莫的核心观点是相当赞同的。以我的理解,老莫观点的核心在于“按需应变,不要拘泥于某种
特定的框架或套路;应该抓住的是本质的东西,例如DRY”。我相信老莫假如是本来把一些业务逻辑写在UI层,而当他遇到类似上面描述的测试需求时,他也
会毫不犹豫地把一些代码重新抽取出来放入一个中间层(不管这个层叫做什么名称)。
这一个线索的贴子讨论得相当精彩。我潜水看这个系列,印证我自己在工作中的体会,也都受益匪浅。呵呵。近期在做WEB开发,WEB也有MVC三个层次的
划分,其中的View、Control、Model就大致对应于UIL、BLL、DAL吧。基本能够套用这个讨论之中的很多观点。
关于这个"同样的东西,在wrapper中测试,比在UI中的一个模块中测试,哪种更加方便高效"的问题,就我近期遇到的体会补充两句。同样的东西,放
在View中实现与放在Control中实现,代码量基本持平;将来业务变更时,要更改也是只更改一个地方。这方面,没有什么差别。但从测试的角度说,
业务逻辑最好还是放在Control层,会比较方便。因为大多数WEB框架的control层都是实现为一批功能函数,可以用成熟的代码级
UnitTest手段来测试。如果是放在View层(即UI层),那么测试的时候,就涉及到要在一定程度上模拟浏览器的行为甚至模拟鼠标键盘操作才能进
行测试,就比较麻烦了。
莫华枫:
用Petshop这种业务逻辑空虚的例子说明不了问题,一般的系统都不会简单到完全是UI直接到CURD。
一个设计良好的可重用的系统抽象,自然而然会呈现出这三层。
抛开部署、伸缩性、应对变化等因素,如果开发人员足够自觉,的确没有必要如此严格分开这三层的依赖关系,
但可惜的是你不能寄望开发人员在急于修改或新增一个个feature的时候违背了这种精神,系统就会非常迅速地腐化。
可能前面的我没有很详细的看.讨论的前提我默认为是现在流行的web application.我现在是做java的.目前的开发的话.增删改查都是有工具自动生成skelton,工作量不是很大.而主要的时间还是在业务逻辑实现上.就是所谓的wrapper上,我们称为service类.按照分层概念将业务层抽取接口暴露方法.这类系统主要的功能逻辑都是放在server端的.
我不知道你说的这些论点是基于什么样的系统里.太宽泛而言的话没有针对性也不具适应性.对系统的看法上我比较赞同javaeye上一篇文章的的观点:web应用而言,只有b系统和s系统.就是在浏览器上的系统和服务器端系统.现在的web应用基本向这两方面开始分化演变,换个说法就是现在的bs系统是b系统和s系统结合的应用,就比如我们现在用的gmail.仔细分析的话到底什么是ui呢,其实b端的东西未必都是ui,如今的webapp上b端已经开始系统化.就UI上的逻辑实现的话.希望老莫能够详细的说一下.
另一方面,理论上,三层模型是为了提高系统的灵活性,把系统的变化局限在某个层次。但这仅仅是理论上的。要发挥三层模型的最佳效能,最好是上层的变化比下曾更大。但在实际中,反倒是一些基础的东西,比如业务类的结构,逻辑关系,变化的很多。同时,业务逻辑和UI的关系也比预想的紧密。因而,很多原本BLL的操作、约束被移到UI,从而造成BLL的空置。
On 12月9日, 下午2时59分, "莫华枫" <longshank...@gmail.com> wrote:
> 我见到过一种三层模型,分为UI、BLL、DAL。此外还有一组Model类,用于封装实际的业务对象。这没什么特别的,多数三层模型都是这样。但是,这种三层 模型有个特殊的地方,对于每一个描述业务对象的Model类,在BLL里基本上都有一个类对应,实时查询、检索等等操作。差不多就是个管理类吧。但如果深入到这 些类内部,发现它们只是一组wrapper。其内部保有一个对象,该对象的类来自于DAL。而BLL中的这些类上的操作在DAL相对应的类上都有。BLL类实际 只是在转发操作,而真正工作的,是DAL中的那一组类。
>
> 我觉得很奇怪,为什么要凭空锻造出这么一组毫无用处的类呢?得到的答案是:从MS的案例中学来的。诧异之余,我未免心中起疑,MS再差劲,也不至于直眉瞪眼地破 坏DRY吧。肯定是这些家伙学艺不精,会错MS的意了。
>
> 不久前,公司来了一个应聘者,走的是.net <http://xn--0iv967a7jr.net>
> 路线,在外做过几个项目。我们出编程题考他,结果他做的程序的结构也是三层模型,居然和上面所说的结构一模一样,也是在BLL中放了一组无用的wrapper。 关键是,此人和那个三层模型的创造者此前完全不可能相识。那么,只有两种可能。要么是他们以同样的方式错误理解了MS的案例;要么就是MS的案例本来就是这样的 。
>
> MS的案例究竟如何,我没有考证过,也无意去关心。我想到的是一个程序员如何开始学习编程。很多程序员喜欢从案例开始学习。从抄写代码,慢慢变为小修小改,然后 逐步理解,最后开始单飞。但是,这里有个问题。程序员就像小鸟。小鸟会把第一眼看见的会动的东西当成妈妈,而程序员则会把最初学习的案例当成典范。
>
> 因而,程序员最初开始的编程学习就显得非常重要。一旦定型,以后很难改掉。一个程序员最初不应该从某些应用型的案例中开始学习。更多地应该把精力放在基本功上, 像基本的编程原则、算法、范式等等。并且从一些小案例开始,比如写个小算法、小工具等等。此时的程序员还缺乏判断力,无法认清那些复杂案例中的问题和陷阱。上面 提到的这种三层模型,我相信ms原意并非如此。但是,涉世不深的程序员很容易误解其中的用意,然后加以发挥。在没有正确引导的情况下,误入歧途。
>
> 可是,现实往往是残酷的。很多程序员并没有机会获得完善的培训。他们在大学里没有打好基础,来到工作单位就立刻投入开发工作,很多都是从接手和维护其他人的代码 开始。企业希望以此快速地培养出程序员。但是这也往往使得那些代码中原本存在的缺陷被新手们充分吸收。老程序员往往无暇顾及那些新人。有时,甚至他们自身也未曾 意识到存在的问题。这样,错误就一代接一代地传了下去。
>
> 指出了这些问题之后,我却不知道有什么好方法能够破解。我能想到的唯一方法就是,趁自己工作前,或者技术定型之前,打好基础,开拓眼界。不要迷信案例,带着怀疑 的眼光和基本原则来看待他们。多问(不是在这里哈),多想,多google,多wiki,还有多上TopLanguage。:P
>
> --
> 反者道之动,弱者道之用
> m...@seaskysh.com
> longshank...@gmail.comhttp://blog.csdn.net/longshanks/
我想,我不是做web服务的,我从我的思考角度出发。
BLL层应该包含哪些东西呢,有很明显的原则性的东西来指示区分吗?而DAL仅仅是负责数据的访问和存储。
按照我的想法,举个例子。例如在一个提供并行处理的服务中(例如云计算,这个时髦),存储数据这个东西,是属于业务处理范畴呢,还是属于数据访问范畴
呢?我的意思是:用户指定想保存到某个地点。(例如,考虑到云计算分布式特点,数据存储位置有不确定性,说不定有公司会提供专门的存储业务,提供让用户
满意的数据安全)
我想,这个应该是属于BLL层的东西吧。
就像有人说的,给员工提高10%的工资,是通过sql 做还是通过java类做,这一层究竟算业务逻辑还是数据逻辑,问题关键或者核心我想就在这里。
On 12月16日, 上午10时12分, "up duan" <fixo...@gmail.com> wrote:
> 2008/12/16 Justin L <icer...@gmail.com>
蒙同学经学学廖平,佛学从欧阳竟无,又曾问故于章太炎,不亏是高手,
精辟啊。
可惜现在市面上的入门书,好的不多,就是有好的,也卖得一般,郁闷。
一个典型,C语言卖得最火的,还是谭浩强……
On 12月9日, 下午2时59分, "莫华枫" <longshank...@gmail.com> wrote:
>
> 因而,程序员最初开始的编程学习就显得非常重要。一旦定型,以后很难改掉。
当然,还有一个办法就是坚持"科学精神",不断地怀疑和否定,不断地加深加宽自己的知识面,这样也可以避免入门路径的偏差导致见识的偏差。